1. 程式人生 > >solidity using A for B與import區別

solidity using A for B與import區別

前言


其實呢,今天剛接觸Using for的時候,我並沒有看懂它的意思。官方的文件有些晦澀難懂,導致我也產生了它與import的區別這樣的疑問。

使用


與import的聯絡與區別
先回答第二個問題,using A for B與import有什麼區別?

import是講某個合約contract或者某個庫lib匯入到當前檔案,它是using的前提;import後,當前檔案內可以引用被引入檔案內定義的library或contract。 
舉個例子: 
 
這裡,如果沒有先import,直接using,會報錯。除非別的被import的檔案再import了它。換句換說,就是

using的前提是需要直接或者間接的匯入某個library.

Using for 如何使用
using A for B,這裡A通常是某個library裡面定義的某個方法,B是某種資料型別,這句話是把A方法繫結到B型別上,相當於給B型別附加了一個A方法。(也有翻譯為附著庫的) 
在上面的例子中,將LibContract裡定義的方法繫結到所有的資料型別。但是一般我們不會在所有的型別例項上都去呼叫LibContract的方法,應該是要按需using的,這裡偷懶就寫*。 
在通俗一點的例子就是, 
比如 using LibInt for uint,然後LibInt裡面有定義一個toString方法。我們有一個uint a;那麼可以這樣呼叫a.toString(),toString方法在定義的時候,第一個引數會是一個uint型別的變數,表示呼叫者。

using A for B,A的函式的第一個引數必須和B的資料型別一致。

還有這個方法是可以過載的,你可以定義好幾個同名的方法,但是第一個引數的型別不同,呼叫的時候自動的根據呼叫型別選擇某一種方法。

例項1

pragma solidity ^0.4.16;

library Set {
  struct Data { mapping(uint => bool) flags; }

  function insert(Data storage self, uint value)
      public
      returns (bool)
  {
      if (self.flags[value])
        return false; // already there
      self.flags[value] = true;
      return true;
  }

  function remove(Data storage self, uint value)
      public
      returns (bool)
  {
      if (!self.flags[value])
          return false; // not there
      self.flags[value] = false;
      return true;
  }

  function contains(Data storage self, uint value)
      public
      view
      returns (bool)
  {
      return self.flags[value];
  }
}

contract C {
    using Set for Set.Data;
    Set.Data knownValues;

    function register(uint value) public {
        // 相當於Set.insert(knownValues, value)
        require(knownValues.insert(value));
    }
}

例項2:

pragma solidity ^0.4.16;

library Search {
    function indexOf(uint[] storage self, uint value)
        public
        view
        returns (uint)
    {
        for (uint i = 0; i < self.length; i++)
            if (self[i] == value) return i;
        return uint(-1);
    }
}

contract C {
    using Search for uint[];
    uint[] data;

    function append(uint value) public {
        data.push(value);
    }

    function replace(uint _old, uint _new) public {
        uint index = data.indexOf(_old);
        if (index == uint(-1))
            data.push(_new);
        else
            data[index] = _new;
    }
}