6. Solidity:引用类型变量:映射

2023-09-26  本文已影响0人  泡泡龙吐泡泡

6.1 映射的声明

映射(mapping)是Solidity中的哈希表,实现通过key值查询对应的Value,例如:通过调用者的地址查询其余额。声明映射的格式为:mapping(_keyType => _valueType)

示例代码:

    // 声明映射   (钱包地址的余额)
    mapping (address => uint) public balances;
    // 声明嵌套映射    (两个地址是否为朋友关系)
    mapping (address => mapping (address => bool)) public isFriend;

6.2 映射相关操作

映射的设置、查询、删除操作示例:


    // ***************************映射***************************
    // 设置
    function setBalance(uint _balance) external {
        balances[msg.sender] = _balance;
    }

    // 查询
    function getBalance() external view returns (uint) {
        return balances[msg.sender];
    } 

    // 删除
    function deleteBalance() external {
        delete balances[msg.sender];    // 余额设置为默认值:0
    }

    // ***************************嵌套映射***************************
    // 设置
    function setFriend() external {
        // 设置合约地址为调用者的朋友
        isFriend[msg.sender][address(this)] = true;
    }

    // 查询
    function getFriend() external view returns (bool) {
        return isFriend[msg.sender][address(this)];
    }

    // 删除
    function deleteFriend() external {
        delete isFriend[msg.sender][address(this)];
    }

Solidity中所有数据都有默认值,查询不存在的(未赋值的)key对应的value,并不会报错,而会返回value类型的默认值。
例如,在没有调用设置方法(setBalance()、setFriend())的情况下,调用查询方法getBalance()会返回uint类型的默认值0,调用查询方法getFriend()会返回bool类型的默认值false。

6.3 映射的规则

Types containing (nested) mappings can only be parameters or return variables of internal or library functions.

6.4 映射的原理

6.5 可遍历映射

根据原理一,映射不储存任何键(Key)的信息(例如哪些Key被使用),也没有length的信息,因此solidity中映射类型本身不可遍历。
可以通过以下方式实现可遍历映射:

一个可遍历映射示例:

contract IterableMapping {
    mapping (address => uint) public balances;
    // 记录某一个地址(key)是否存在于映射中
    mapping (address => bool) public inserted;
    // 记录所有存在的地址(key)
    address[] public keys;

    // 设置键值对
    function set(address _key, uint _value) external {
        // 设置键值对
        balances[_key] = _value;
        // 判断键值对在设置前是否存在
        if (!inserted[_key]) { // false
            inserted[_key] = true;
            keys.push(_key);
        }
    }

    // 根据索引获取value
    function get(uint _i) external view returns (uint) {
        require(_i < keys.length, "index out of range");
        return balances[keys[_i]];
    }

    // 余额汇总
    function getTotal() external view returns (uint sum) {
        for (uint i = 0;i < keys.length;i++) {
            sum += balances[keys[i]];
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读