映射/字典(mappings)
优质
小牛编辑
134浏览
2023-12-01
映射
或字典类型,一种键值对的映射关系存储结构。定义方式为mapping(_KeyType => _KeyValue)
。键的类型允许除映射
外的所有类型,如数组,合约,枚举,结构体。值的类型无限制。
映射
可以被视作为一个哈希表,其中所有可能的键已被虚拟化的创建,被映射到一个默认值(二进制表示的零)。但在映射表中,我们并不存储键的数据,仅仅存储它的keccak256
哈希值,用来查找值时使用。
因此,映射
并没有长度,键集合(或列表),值集合(或列表)这样的概念。
映射
类型,仅能用来定义状态变量
,或者是在内部函数中作为storage
类型的引用。引用是指你可以声明一个,如var storage mappVal
的用于存储状态变量的引用的对象,但你没办法使用非状态变量来初始化这个引用。
可以通过将映射
标记为public
,来让Solidity创建一个访问器。要想访问这样的映射
,需要提供一个键值做为参数。如果映射
的值类型也是映射
,使用访问器访问时,要提供这个映射
值所对应的键,不断重复这个过程。下面来看一个例子:
contract MappingExample{
mapping(address => uint) public balances;
function update(uint amount) returns (address addr){
balances[msg.sender] = amount;
return msg.sender;
}
}
由于调试时,你不一定方便知道自己的发起地址,所以把这个函数,略微调整了一下,以在调用时,返回调用者的地址。编译上述合同后,可以先调用update()
,执行成功后,查看调用信息,能看到你更新的地址,这样再查一下这个地址的在映射里存的值。
如果你想通过合约进行上述调用。
pragma solidity ^0.4.0;
//file indeed for compile
//may store in somewhere and import
contract MappingExample{
mapping(address => uint) public balances;
function update(uint amount) returns (address addr){
balances[msg.sender] = amount;
return msg.sender;
}
}
contract MappingUser{
address conAddr;
address userAddr;
function f() returns (uint amount){
//address not resolved!
//tringing
conAddr = hex"0xf2bd5de8b57ebfc45dcee97524a7a08fccc80aef";
userAddr = hex"0xca35b7d915458ef540ade6068dfe2f44e8fa733c";
return MappingExample(conAddr).balances(userAddr);
}
}
映射
并未提供迭代输出的方法,可以自行实现一个数据结构。参见iterable mapping。