Iterable Mapping 可迭代映射
您不能遍历mapping. 所以这里是一个如何创建可迭代的示例mapping。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; library IterableMapping { // Iterable mapping from address to uint; struct Map { address[] keys; mapping(address => uint) values; mapping(address => uint) indexOf; mapping(address => bool) inserted; } function get(Map storage map, address key) public view returns (uint) { return map.values[key]; } function getKeyAtIndex(Map storage map, uint index) public view returns (address) { return map.keys[index]; } function size(Map storage map) public view returns (uint) { return map.keys.length; } function set( Map storage map, address key, uint val ) public { if (map.inserted[key]) { map.values[key] = val; } else { map.inserted[key] = true; map.values[key] = val; map.indexOf[key] = map.keys.length; map.keys.push(key); } } function remove(Map storage map, address key) public { if (!map.inserted[key]) { return; } delete map.inserted[key]; delete map.values[key]; uint index = map.indexOf[key]; uint lastIndex = map.keys.length - 1; address lastKey = map.keys[lastIndex]; map.indexOf[lastKey] = index; delete map.indexOf[key]; map.keys[index] = lastKey; map.keys.pop(); } } contract TestIterableMap { using IterableMapping for IterableMapping.Map; IterableMapping.Map private map; function testIterableMap() public { map.set(address(0), 0); map.set(address(1), 100); map.set(address(2), 200); // insert map.set(address(2), 200); // update map.set(address(3), 300); for (uint i = 0; i < map.size(); i++) { address key = map.getKeyAtIndex(i); assert(map.get(key) == i * 100); } map.remove(address(1)); // keys = [address(0), address(3), address(2)] assert(map.size() == 3); assert(map.getKeyAtIndex(0) == address(0)); assert(map.getKeyAtIndex(1) == address(3)); assert(map.getKeyAtIndex(2) == address(2)); } }