我做了很多我不能理解的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
一次,我不明白为什么第一个输出也改变,打破了控制流
2条答案
按热度按时间0md85ypi1#
这不是重新分配一个应该是const的东西的问题,而是用另一个同名的常量来隐藏一个常量的问题。
第一个常量具有全局作用域,但第二个常量存在于
main()
函数的作用域中。在这个函数中,如果我们引用I
,它将在较小的封闭作用域中找到,即main()
函数。在下面的修改示例中,我引入了一个新的块来说明这一点。从
gi
的Angular 来看,I
是在全局范围内找到的,但是一旦进入人工块I
就引用了它的第二个定义(在这个块中)。令人困惑的部分是,即使内部常量是在引用它的语句之后定义的,也会找到它。如果它是一个变量,它就不正确,但因为它是一个常数,顺序并不重要(这就像一个词汇替换)。如果顶部的
I
出现在main()
函数的下面,情况也是一样的:它将存在于全局范围内。41ik7eoe2#
注意,
I
不是全局变量,而是一个常量,这是不一样的。常数不能更新,因为它们在编译时计算。此外,Rust有关于阴影的词汇规则。本地名称将始终覆盖非本地名称。您在这里使用了
#![allow(unused)]
,这让我认为您可能已经看到了以下警告,但没有注意它,而是选择忽略它:这是相当明确的,虽然指出,你从来没有真正使用外部的
I
在您的代码,但内部的。最后,对于常量和函数,声明的顺序并不重要,所以在函数体的中间声明常量与在顶部声明常量是一样的。
根据前面的解释,可以推断您的示例等效于: