const 变量返回两个不同的值

Rus*_*ted 7 rust

今天我对 nightly 模块做了一些测试std::lazy它在局部变量中运行良好。然而,当我定义一个const变量时,它给了我两个不同的值。似乎 Colsure 被调用了多次。

#![feature(once_cell)]
use rand::Rng; // 0.8.4
use std::lazy::Lazy;

const CONST_LAZY: Lazy<i32> = Lazy::new(|| rand::thread_rng().gen::<i32>());

fn main() {
    let local_lazy: Lazy<i32> = Lazy::new(|| rand::thread_rng().gen::<i32>());
    println!("{}", *local_lazy); // -1475423855
    println!("{}", *local_lazy); // -1475423855

    println!("{}", *CONST_LAZY); // 1975106939
    println!("{}", *CONST_LAZY); // -1848043613
}
Run Code Online (Sandbox Code Playgroud)

Mas*_*inn 9

这是我的代码,谁能告诉我为什么?

因为你令人困惑const并且static.

根据官方文档

常量是一个可选命名的常量值,它与程序中的特定内存位置无关。无论在何处使用常量,本质上都是内联的,这意味着它们在使用时会直接复制到相关上下文中。这包括使用外部包中的常量和非Copy类型。对同一常量的引用不一定保证引用同一内存地址。

(请注意,最后一句的措辞表明 const可以提升为静态并共享内存地址,但不能保证,虽然静态可以内联,但它可能不应该通过安全 rust 来观察,因此应该是无关的)。

本质上,您的代码片段在语义上等同于:

#![feature(once_cell)]
use rand::Rng; // 0.8.4
use std::lazy::Lazy;

fn main() {
    let local_lazy: Lazy<i32> = Lazy::new(|| rand::thread_rng().gen::<i32>());
    println!("{}", *local_lazy);
    println!("{}", *local_lazy);

    println!("{}", *Lazy::new(|| rand::thread_rng().gen::<i32>()));
    println!("{}", *Lazy::new(|| rand::thread_rng().gen::<i32>()));
}
Run Code Online (Sandbox Code Playgroud)

这也是它编译的原因,因为它Lazy不是线程安全的,因此实际的全局 (a static) 将不会编译,因为它可以在线程之间共享。