用通俗易懂的方式解释 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
?
-
节省 Gas:
-
view
和pure
函数如果被外部调用(通过交易),不需要消耗 Gas(但如果被其他合约内部调用,可能消耗 Gas)。
-
-
明确意图:
-
开发者一看就知道这个函数是否会修改合约状态,避免意外操作。
-
-
编译器检查:
-
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
:与世隔绝(不读也不改数据,只靠输入参数)。