用通俗易懂的方式解释 Solidity 中的 view 和 pure

用通俗易懂的方式解释 Solidity 中的 view 和 pure,并举例说明:


1. view(视图函数)

是什么?
  • 只读模式view 函数可以读取合约中的数据(如状态变量),但不会修改合约状态(不会改变链上数据)。

  • 类比:就像查看银行账户余额,你只能看,不能动里面的钱。

例子

solidity代码:

contract Bank {
    uint public totalMoney = 1000; // 状态变量(链上存储的总金额)

    // view 函数:读取 totalMoney,但不修改它
    function getTotalMoney() public view returns (uint) {
        return totalMoney; 
    }

    // ❌ 错误示例:如果在 view 函数中修改状态变量,会编译失败
    function badFunction() public view {
        totalMoney = 2000; // 报错!view 函数不能修改状态
    }
}

2. pure(纯函数)

是什么?
  • 完全独立pure 函数既不读取合约数据,也不修改合约状态,仅根据输入参数计算结果。

  • 类比:就像数学计算器中的加法,只依赖输入的数字,不涉及任何外部数据。

例子

solidity代码:

contract Calculator {
    // pure 函数:仅用输入参数计算,不读/写状态变量
    function add(uint a, uint b) public pure returns (uint) {
        return a + b;
    }

    // ❌ 错误示例:如果在 pure 函数中读取状态变量,会编译失败
    uint public num = 10;
    function badFunction() public pure returns (uint) {
        return num; // 报错!pure 函数不能读取状态变量
    }
}

对比总结

修饰符 能读状态变量? 能写状态变量? 依赖输入参数? 典型用途
view 可选 查询余额、获取合约配置
pure 数学计算、数据格式转换

3. 为什么需要 view 和 pure

  1. 节省 Gas

    • view 和 pure 函数如果被外部调用(通过交易),不需要消耗 Gas(但如果被其他合约内部调用,可能消耗 Gas)。

  2. 明确意图

    • 开发者一看就知道这个函数是否会修改合约状态,避免意外操作。

  3. 编译器检查

    • Solidity 编译器会强制检查函数是否符合 view 或 pure 的规则,防止错误。


4. 实际应用场景

view 的典型场景

solidity代码:

// 查询用户余额
mapping(address => uint) public balances;

function getBalance(address user) public view returns (uint) {
    return balances[user];
}
pure 的典型场景

solidity代码:

// 计算两个数的最大值
function max(uint a, uint b) public pure returns (uint) {
    return a > b ? a : b;
}

5. 注意事项

  • 旧版本兼容性

    • 在 Solidity 0.4.x 版本中,view 和 pure 的语法是 constant,但现已废弃。

  • 强制声明

    • 如果函数不读取也不修改状态,必须声明为 pure;如果只读取不修改,必须声明为 view,否则编译器会报错。


一句话总结

  • view:能看不能摸(读数据,不修改数据)。

  • pure:与世隔绝(不读也不改数据,只靠输入参数)。