🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 常量(constant state variables) `状态变量`可以被定义为`constant`,常量。这样的话,它必须在编译期间通过一个表达式赋值。赋值的表达式不允许:1)访问`storage`;2)区块链数据,如`now`,`this.balance`,`block.number`;3)合约执行的中间数据,如`msg.gas`;4)向外部合约发起调用。也许会造成内存分配副作用表达式是允许的,但不允许产生其它内存对象的副作用的表达式。内置的函数`keccak256`,`keccak256`,`ripemd160`,`ecrecover`,`addmod`,`mulmod`可以允许调用,即使它们是调用的外部合约。 允许内存分配,从而带来可能的副作用的原因是因为这将允许构建复杂的对象,比如,查找表。虽然当前的特性尚未完整支持。 编译器并不会为常量在`storage`上预留空间,每个使用的常量都会被对应的常量表达式所替换(也许优化器会直接替换为常量表达式的结果值)。 不是所有的类型都支持常量,当前支持的仅有值类型和字符串。 ``` pragma solidity ^0.4.0; contract C { uint constant x = 32**22 + 8; string constant text = "abc"; bytes32 constant myHash = keccak256("abc"); } ``` ### 常函数(Constant Functions) 函数也可被声明为常量,这类函数将承诺自己不修改区块链上任何状态。 ``` pragma solidity ^0.4.0; contract C { function f(uint a, uint b) constant returns (uint) { return a * (b + 42); } } ``` `访问器(Accessor)`方法默认被标记为`constant`。当前编译器并未强制一个`constant`的方法不能修改状态。但建议大家对于不会修改数据的标记为`constant`。