关于const
,rust docs state(强调我的):
常量适用于程序的整个生命周期。更具体地说,Rust中的常量在内存中没有固定地址。 这是因为它们有效地内联到他们使用的每个地方。由于这个原因,对同一个常量的引用不一定保证引用相同的内存地址。
所以,我想知道const数组是如何“有效内联的”。请参阅以下代码段中的我的评论:
const ARR: [i32; 4] = [10, 20, 30, 40];
fn main() {
// is this
println!("{}", ARR[1]);
// the same as this?
println!("{}", [10, 20, 30, 40][1]);
// or this?
println!("{}", 20);
}
我感谢任何澄清!
答案 0 :(得分:6)
这取决于。答案是"以上所有,可能。"让我们稍微修改一下你的例子:
const ARR: [i32; 4] = [10, 20, 30, 40];
#[inline(never)] fn show(v: i32) { println!("{}", v); }
fn main() {
// is this
show(ARR[1]);
// the same as this?
show([10, 20, 30, 40][1]);
// or this?
show(20);
}
现在,让我们将其编译为LLVM IR,看看main
函数的样子:
define internal void @_ZN4main20hf87c9a461739c547ZaaE() unnamed_addr #4 {
entry-block:
call void @_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
call void @_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
call void @_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
ret void
}
对show
函数的三次相同调用,每次调用都传递一个常量20
。即使启用了优化,这也是不可能的!
就语言保证的内容而言,对show
的前两次调用在语义上是相同的。说一个常数是"内联"并不意味着它会自动导致围绕它的所有内容;它只是使值被替换到位。但是,由于Rust的侵略性常量折叠和内联,这三个在实践中是 ,在这个特定情况下是。