范围和声明
声明的变量将具有一个初始默认值,其字节表示全为零。变量的“默认值”是任何类型的典型“零状态”。例如,a 的默认bool 值为false。uint或int 类型的默认值为0。对于静态大小的数组和bytes1to bytes32,每个单独的元素将被初始化为其类型对应的默认值。对于动态大小的数组bytes 和string,默认值为空数组或字符串。对于该enum类型,默认值是它的第一个成员。
Solidity 中的作用域遵循 C99(和许多其他语言)的广泛作用域规则:变量从声明后的那一点到包含声明的最小块的末尾都是可见的。作为此规则的一个例外,在 for 循环的初始化部分中声明的变量仅在 for 循环结束之前可见。{ }
类似参数的变量(函数参数、修饰符参数、catch 参数……)在后面的代码块中可见 - 函数体/修饰符的函数和修饰符参数以及 catch 参数的 catch 块。
在代码块之外声明的变量和其他项目,例如函数、契约、用户定义的类型等,甚至在声明之前就可见。这意味着您可以在声明和递归调用函数之前使用状态变量。
因此,以下示例将在没有警告的情况下编译,因为这两个变量具有相同的名称但范围不相交。
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; contract C { function minimalScoping() pure public { { uint same; same = 1; } { uint same; same = 3; } } }
作为 C99 范围规则的一个特殊示例,请注意,在下文中,第一次赋值x将实际分配外部变量而不是内部变量。在任何情况下,您都会收到有关外部变量被遮蔽的警告。
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; // This will report a warning contract C { function f() pure public returns (uint) { uint x = 1; { x = 2; // this will assign to the outer variable uint x; } return x; // x has value 2 } }
警告
在 0.5.0 版本之前,Solidity 遵循与 JavaScript 相同的范围规则,也就是说,在函数内任何地方声明的变量都将在整个函数的范围内,无论它在哪里声明。以下示例显示了一个用于编译但从 0.5.0 版本开始导致错误的代码片段。
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; // This will not compile contract C { function f() pure public returns (uint) { x = 2; uint x; return x; } }
更多建议: