Solidity 映射 mapping
Solidity 映射 mapping 用于以键值对的形式存储数据,等同于其它编程语言的哈希表或字典。
映射 mapping 是智能合约中很常用的一种数据类型,它是引用类型。
下面是声明映射类型的语法。
mapping(_KeyType => _ValueType)
- _KeyType:可以是任何内置类型,或者 bytes 和 字符串。不允许使用引用类型或复杂对象。
- _ValueType: 可以是任何类型。
注意
- 映射的数据位置(data location)只能是 storage,通常用于状态变量。
- 映射可以标记为 public,Solidity 自动为它创建 getter。
映射可以视作哈希表 ,它们在实际的初始化过程中创建每个可能的 key,并将其映射到字节形式全是零的值:一个类型的 默认值。
映射与哈希表不同:在映射中,实际上并不存储 key,而是存储它的 keccak256 哈希值,从而便于查询实际的值。
正因为如此,映射是没有长度的,也没有 key 的集合或 value 的集合的概念。映射只能是存储的数据位置,因此只允许作为状态变量或作为函数内的存储引用 或 作为库函数的参数。 它们不能用于合约公有函数的参数或返回值。
可以将映射声明为 public,然后来让 Solidity 创建一个 getter 函数。 _KeyType 将成为 getter 的必须参数,并且 getter 会返回 _ValueType。
1. 状态变量示例
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract LedgerBalance { mapping(address => uint) public balances; function updateBalance(uint newBalance) public { // 设置 mapping 的 key 和 value balances[msg.sender] = newBalance; } function get() public view returns(uint){ // 通过 key 获取 mapping 的 value return balances[msg.sender]; } } contract Updater { function updateBalance() public returns (uint) { LedgerBalance ledgerBalance = new LedgerBalance(); ledgerBalance.updateBalance(10); return ledgerBalance.get(); } }
运行上述程序,先单击 updateBalance 按钮将值设置为 10,然后查看日志输出:
{ "0": "uint256: 10" }
2. 局部变量示例
mapping 类型可以用做局部变量,但只能引用状态变量,而且存储位置为 storage。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract LedgerBalance { mapping(address => uint) public balances; function updateBalance() public returns (uint) { // mapping 局部变量 ref 引用状态变量 balances mapping(address => uint) storage ref = balances; ref[msg.sender] = 3; return 0; } }
下一章:Solidity 枚举 enum
solidity 的枚举类型 enum 是一种用户自定义类型,用于表示多种状态。枚举类型 enum 内部就是一个自定义的整型,默认的类型为uint8,当枚举数足够多时,它会自动变成uint16。枚举类型 e ...