Solidity中形参使用storage关键字声明会发生

212 阅读2分钟

在函数参数中使用storage关键字是无效的,因为storage关键字只用于声明合约的状态变量,而不适用于函数的形参。函数参数默认为memory类型。

如果您在函数形参中使用了storage关键字,编译器将会报错,提示无效的关键字。

以下是一个示例,展示了在函数形参中使用storage关键字导致的错误:

pragma solidity ^0.8.0;

contract ParameterExample {
    uint256 public data;

    function setData(storage uint256 _data) public {
        data = _data;
    }
}

在上述示例中,我们在setData函数的形参前添加了storage关键字,这是无效的。编译器将会报告以下错误:

ParserError: Expected identifier but got 'storage'

所以,请确保在函数的形参中不要使用storage关键字,它只适用于合约的状态变量声明。函数参数默认为memory类型,您可以直接使用参数名来操作函数参数的数据。

但是会存在以下使用场景

pragma solidity ^0.4.25;
//角色库(管理所有角色地址)
// 1. 实现增加角色地址
// 2. 移除角色地址
// 3. 判断角色地址是否被授权
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

此处storage关键字用于指定在函数参数中使用的是对状态变量的引用,而不是复制状态变量的值。这样可以直接修改传入的状态变量,而不是创建一个新的副本。

在上述代码中,函数addremovehas中的Role storage参数表示将Role结构体作为引用传递,以便直接修改传入的Role对象。