title | tags | ||||
---|---|---|---|---|---|
7. 映射类型 |
|
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
这一讲,我们将介绍映射(Mapping
)类型,Solidity中存储键值对的数据结构,可以理解为哈希表。
在映射中,人们可以通过键(Key
)来查询对应的值(Value
),比如:通过一个人的id
来查询他的钱包地址。
声明映射的格式为mapping(_KeyType => _ValueType)
,其中_KeyType
和_ValueType
分别是Key
和Value
的变量类型。例子:
mapping(uint => address) public idToAddress; // id映射到地址
mapping(address => address) public swapPair; // 币对的映射,地址到地址
-
规则1:映射的
_KeyType
只能选择Solidity内置的值类型,比如uint
,address
等,不能用自定义的结构体。而_ValueType
可以使用自定义的类型。下面这个例子会报错,因为_KeyType
使用了我们自定义的结构体:// 我们定义一个结构体 Struct struct Student{ uint256 id; uint256 score; } mapping(Student => uint) public testVar;
-
规则2:映射的存储位置必须是
storage
,因此可以用于合约的状态变量,函数中的storage
变量和library函数的参数(见例子)。不能用于public
函数的参数或返回结果中,因为mapping
记录的是一种关系 (key - value pair)。 -
规则3:如果映射声明为
public
,那么Solidity会自动给你创建一个getter
函数,可以通过Key
来查询对应的Value
。 -
规则4:给映射新增的键值对的语法为
_Var[_Key] = _Value
,其中_Var
是映射变量名,_Key
和_Value
对应新增的键值对。例子:function writeMap (uint _Key, address _Value) public{ idToAddress[_Key] = _Value; }
-
原理1: 映射不储存任何键(
Key
)的资讯,也没有length的资讯。 -
原理2: 对于映射使用
keccak256(h(key) . slot)
计算存取value的位置。感兴趣的可以去阅读 WTF Solidity 内部规则: 映射存储布局 -
原理3: 因为Ethereum会定义所有未使用的空间为0,所以未赋值(
Value
)的键(Key
)初始值都是各个type的默认值,如uint的默认值是0。
这一讲,我们介绍了Solidity中哈希表——映射(Mapping
)的用法。至此,我们已经学习了所有常用变量种类,之后我们会学习控制流if-else
,while
等。