Solidity 映射(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: SimPL-3.0
pragma solidity ^0.7.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: SimPL-3.0
pragma solidity ^0.7.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 ;
   }
}

Solidity允许类型之间进行隐式转换和显式转换。 1. 隐式转换隐式转换时必须符合一定条件,不能导致信息丢失。例如,uint8可以转换为uint16,但是int8不可以转换为uint256,因为in ...