函数含同名变量时如何访问Solidity状态变量及修改等疑问
Solidity中状态变量与同名参数的访问与修改问题
我知晓函数参数与状态变量同名并非良好实践,此问题仅出于好奇提出。经实验验证,以下Solidity代码可正常运行:
pragma solidity ^0.8.0; import "hardhat/console.sol"; contract MyContract { uint256 public publicUint256; constructor() { publicUint256 = 100; } // test access state variable by this.xxx inside function function accessStateVariable(uint256 publicUint256) public { console.log("publicUint256", publicUint256); console.log("this.publicUint256()", this.publicUint256()); // this gives 100 console.log( "this.publicUint256() + publicUint256", this.publicUint256() + publicUint256 ); } }
由此可知,可通过this.variable()在函数内访问状态变量。针对相关疑问解答如下:
1. this.variable()与直接使用variable的区别
- 作用域优先级:直接使用
variable会优先匹配函数参数(局部作用域),而this.variable()是调用Solidity为public状态变量自动生成的getter函数,访问的是合约的全局状态变量。 - 调用开销:
this.variable()属于外部函数调用(即使是自身调用),会产生EVM调用的额外开销;直接访问状态变量是对存储的直接读取,开销更低。 - 可见性限制:仅public状态变量会自动生成getter函数,因此
this.variable()仅适用于public变量;internal/private状态变量无法通过这种方式访问。
2. 如何修改同名的状态变量
this.variable()是自动生成的getter函数,仅支持读取操作,无法直接修改状态变量。要实现修改,可采用以下方法:
方法一:自定义setter函数
在合约中添加一个public的setter函数,通过this调用它来修改状态变量:
pragma solidity ^0.8.0; import "hardhat/console.sol"; contract MyContract { uint256 public publicUint256; constructor() { publicUint256 = 100; } function setPublicUint256(uint256 newValue) public { publicUint256 = newValue; } function accessStateVariable(uint256 publicUint256) public { // 修改状态变量为200 this.setPublicUint256(200); console.log("updated state variable", this.publicUint256()); } }
方法二:显式使用存储指针
在函数内声明指向状态变量的存储指针,通过指针修改值(此方式需注意作用域解析,不如setter直观):
function accessStateVariable(uint256 publicUint256) public { // 显式声明存储指针指向状态变量 uint256 storage stateVar = this.publicUint256; stateVar = 200; console.log("updated state variable", stateVar); }
注意:第二种方式仅适用于public状态变量,internal/private变量无法通过
this.variable获取存储引用。
内容的提问来源于stack exchange,提问作者Louis Law
相关产品推荐
相关产品推荐

