我用我无法理解的 Rust 全局变量做了很多实验;为什么会发生这种情况
#![allow(unused)]
const I:i32 = 10;
fn main() {
let gi = I;
println!("{}", gi);
const I:i32 = 20;
println!("{}", gi);
}
当我这样做时,我期望这个输出
10
10
但我得到的输出是这样的
20
20
我没有碰过gi
,但当我更改全局变量时它仍然会改变,I
如果我I
在打印后更改gi
一次我不明白为什么第一个输出也会改变,从而破坏了控制流
这不是重新分配一些本来应该是常量的东西的问题,而是用另一个同名的常量来隐藏一个常量的问题。
您的第一个常量具有全局范围,但第二个常量存在于函数范围内
main()
。在这个函数中,如果我们引用I
它,就会发现它是在更小的封闭范围内,这就是函数main()
。在下面的修改示例中,我引入了一个新块来说明这一点。从 的角度来看
gi
,I
是在全局范围内找到的,但是一旦在人工块内部,I
就引用它的第二个定义(在这个块中)。令人困惑的部分是,即使内部常量是在引用它的语句之后定义的,也会找到它。如果它是一个变量,那就不正确,但因为它是一个常量,所以顺序并不重要(这就像词法替换)。
I
如果顶部出现在函数下方,情况也是一样main()
:无论如何,它都会存在于全局范围内。注意,这
I
不是全局变量,而是常量,两者是不一样的。常量无法更新,因为它们是在编译时评估的。此外,Rust 还有关于阴影的词汇规则。本地名称总是会覆盖不太本地的名称。您在这里使用的事实
#![allow(unused)]
让我认为您可能已经看到了以下警告,但没有注意它并选择忽略它:它相当明确地指出,您
I
在代码中实际上从未使用过外部,而是使用了内部。最后,对于常量和函数,声明的顺序并不重要,因此在函数体中间声明常量与在顶部声明它相同。
根据前面的解释,可以推断您的示例相当于: