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;
}
}