不想说话,自闭中..

Solidity的Using for的使用

前言

其实呢,今天刚接触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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
}
}