# 映射/字典(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智能合約文件結構
- 智能合約源文件的基本要素概覽
- 值類型
- 類型
- 布爾
- 整型
- 地址
- 字節數組
- 小數
- 字符串
- 十六進制字面量
- 枚舉
- 函數
- 引用類型
- 引用類型
- 數據位置
- 數組
- 數據結構
- 雜項
- 映射
- 左值運算符
- 類型間的轉換
- 類型推斷
- 單位
- 貨幣單位
- 時間單位
- 語言內置特性
- 特殊變量及函數
- 數學和加密函數
- 地址相關
- 進階
- 入參和出參
- 控制結構
- 函數調用
- 創建合約實例
- 表達式的執行順序
- 賦值
- 作用范圍和聲明
- 異常
- 內聯匯編
- 合約詳解
- 合約
- 可見性或權限控制
- 訪問函數
- 函數修改器
- 常狀態變量
- 回退函數
- 事件
- 繼承
- 接口
- 其它
- 庫
- 狀態變量的存儲模型
- 內存變量的存局
- 調用數據的布局