# 映射/字典(mappings)
`映射`或字典类型,一种键值对的映射关系存储结构。定义方式为`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](https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol)。
- Solidity语言
- 入门说明
- Solidity智能合约文件结构
- 智能合约源文件的基本要素概览
- 值类型
- 类型
- 布尔
- 整型
- 地址
- 字节数组
- 小数
- 字符串
- 十六进制字面量
- 枚举
- 函数
- 引用类型
- 引用类型
- 数据位置
- 数组
- 数据结构
- 杂项
- 映射
- 左值运算符
- 类型间的转换
- 类型推断
- 单位
- 货币单位
- 时间单位
- 语言内置特性
- 特殊变量及函数
- 数学和加密函数
- 地址相关
- 进阶
- 入参和出参
- 控制结构
- 函数调用
- 创建合约实例
- 表达式的执行顺序
- 赋值
- 作用范围和声明
- 异常
- 内联汇编
- 合约详解
- 合约
- 可见性或权限控制
- 访问函数
- 函数修改器
- 常状态变量
- 回退函数
- 事件
- 继承
- 接口
- 其它
- 库
- 状态变量的存储模型
- 内存变量的存局
- 调用数据的布局