Rust 常量数组是如何内联的?

Rust 常量数组是如何内联的?,rust,Rust,关于const,重点是: 常量在程序的整个生命周期内有效。更具体地说,Rust中的常量在内存中没有固定地址这是因为它们被有效地内联到使用它们的每个位置。由于这个原因,对同一常数的引用不一定会引用同一内存地址 因此,我想知道常量数组是如何“有效内联”的。请参阅以下代码段中的注释: const ARR: [i32; 4] = [10, 20, 30, 40]; fn main() { // is this println!("{}", ARR[1]); // the s

关于
const
,重点是:

常量在程序的整个生命周期内有效。更具体地说,Rust中的常量在内存中没有固定地址这是因为它们被有效地内联到使用它们的每个位置。由于这个原因,对同一常数的引用不一定会引用同一内存地址

因此,我想知道常量数组是如何“有效内联”的。请参阅以下代码段中的注释:

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);
}

我感谢任何澄清

那要看情况而定。答案是“可能是以上所有内容。”让我们稍微修改一下您的示例:

const ARR:[i32;4]=[10,20,30,40];
#[inline(never)]fn show(v:i32){println!(“{}”,v);}
fn main(){
//这是吗
显示(ARR[1]);
//和这个一样吗?
节目([10,20,30,40][1]);
//还是这个?
表演(20);
}
现在,让我们将其编译为LLVM IR,并查看
main
函数的外观:

define internal void@_ZN4main20hf87c9a461739c547ZaaE()未命名地址4{
入口区:
调用void@_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
调用void@_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
调用void@_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
ret void
}
show
函数的三个相同调用,每个调用传递一个常量
20
。这甚至还没有启用优化


就语言保证的内容而言,对
show
的前两个调用在语义上是相同的。说一个常量是“内联的”并不意味着它会自动使它周围的所有东西也内联;它只会导致值被替换到位。然而,由于Rust具有侵略性的不断折叠和内联,这三者在实践中都是等效的,在这种特定情况下

这是一个很好的答案,非常感谢。只是重申一下您的答案——常量数组与任何其他常量一样是内联的(就地替换),但rust会通过用索引值替换来自然优化索引数组文字吗?尽管出现了后一种优化,但它并没有正式定义为规范的一部分?@w.brian:我认为最安全的说法是它可以优化它。与大多数优化一样,由于各种原因,它们可能不会发生。即使在非常低的优化级别上,LLVM也可以做到这一点。但它可能不会;据我所知,这不是语言的保证。