Solidity 中的作用域规则遵循了 C99(与其他很多语言一样): 变量将会从它们被声明之后可见,直到一对 { } 块的结束。
这一规则有个例外,在 for 循环语句中初始化的变量,其可见性仅维持到 for 循环的结束。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// 定义合约C
contract C {
// a 变量会在 {} 内生效, 其他地方不生效
function test() public pure {
uint256 a = 1;
a += 1;
}
// for 循环是个例外
function test2() public pure returns (uint256) {
uint256 x = 0;
// 可以声明在{}外面
for (uint256 a = 0; a <= 100; a++) {
x += a;
}
// 虽然是个例外 , 但是还是在for里面, 外面是无法访问的
// a = a + 1;
return x;
}
}
对于参数的变量(函数参数、修改器参数、捕获(catch)参数......) 在后面的代码块中是可见的--
对于函数和修改器参数,在函数/修改器的主体中,
对于捕获参数,在捕获块中。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// 定义合约C
contract A {
function er() public pure {
require(false, "is error");
}
}
// 定义合约C
contract C {
modifier isAdmin(uint256 _value) {
// 这里访问到_value, 也就是前面_max
require(_value == 100, "not is 100");
_;
}
// 对于参数的变量
// 函数接收的 _max,
// 则表示{}均可见,无论for还是if
function test3(uint256 _max) public pure returns (uint256) {
uint256 x = 0;
for (uint256 a = 0; a <= _max; a++) {
x += a;
}
return x;
}
// 对于修改器
function test4(uint256 _max) public pure isAdmin(_max) returns (uint256) {
uint256 x = 0;
for (uint256 a = 0; a <= _max; a++) {
x += a;
}
return x;
}
// 对于try
function test5(address _addr) public pure returns (uint256) {
A ac = A(_addr);
try ac.er() {
// 比如x 只对当前{} 有效
uint256 x = 11111;
return x;
} catch Error(string memory err) {
// 这里的x 与上面的x 不是一个东西
uint256 x = 22222222;
return x;
}
}
// 对于其他方式
function test6() public pure returns (uint256) {
// 这2个a 不是同一个东西
// 虽然这两个变量的名字虽然相同,但作用域不同
{
uint256 a = 1;
}
{
uint256 a = 1222;
return a;
}
}
// 对于其他方式
function test7() public pure returns (uint256) {
uint256 a = 33;
{
// 可以访问修改,外面的变量, 因为在同一个{}内
a = a * 2;
}
{
// 但是并不影响我继续声明 a
uint256 a = 1222;
return a;
}
}
}