rust - 比 thread_local 更有效的替代方案!和lazy_static?

标签 rust global-variables global

我当前正在使用 thread_local! 宏:

thread_local!(static FOO: RefCell<Foo> = RefCell::new(Foo::new()));

我只需要对 FOO 的不可变引用 - 它是只读的。其目的是缓存昂贵计算的结果,以便可以在程序其余部分的许多地方使用该结果,而无需显式传递多个级别的函数和方法调用。

如果没有编写器,Rust 允许多个读取器。

有没有一种方法可以让我在 main() 开始时(或之前)创建一个只读全局变量 FOO 并从多个线程(这些线程是全部在 FOO 初始化后生成)?

我看过lazy_static,但它具有延迟初始化,这意味着存在运行时检查以查看它是否已初始化。我正在寻找仅编译为内存地址(在使用它的代码中)的东西,其中该内存的内容在 main() 开始时(或之前)初始化,并且永远不会改变了。

最佳答案

这确实感觉没有必要,除非是在绝对罕见的性能关键情况下。

有一些 crate (例如 ctor )可以让您在 main 之前进行计算,但大多数 std 不能在 main 之前使用,因此您能做的事情将受到极大限制。如果我们要这样做,那么让我们将其作为 main 中的第一件事:

// result of expensive calculation
#[derive(Debug)]
pub struct Foo(String);

static mut FOO: *const Foo = std::ptr::null();

fn init_foo() {
    // expensive calculation
    let foo = Box::new(Foo(String::from("expensive!")));
    unsafe {
        // leak the value, so it will never be dropped or freed
        FOO = Box::leak(foo) as *const Foo;
    }
}

// public accessor for Foo
pub fn get_foo() -> &'static Foo {
    unsafe {
        &*FOO
    }
}

fn main() {
    // better remember to do this or it's UB!
    init_foo();
    
    println!("foo = {:?}", get_foo());
}

关于rust - 比 thread_local 更有效的替代方案!和lazy_static?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63433547/

相关文章:

c++ - 全局变量可以在C++的各个类中访问和修改吗

使用rust E0061 : Some(A) is not the same as Some(match . .. =>A)

rust - 如何使 rustc-link-search 相对于项目位置?

rust - 如何从派生的NetworkBehaviour发出SwarmEvent::Behaviour?

c++ - 静态变量和全局变量什么时候初始化?

c++ - 包含常量而不导入头文件

http - 如何通过 TcpStream 将 .jpg 作为 HTTP 发送?

java - 从任何地方访问组合框值

javascript - 在没有特定目标的情况下触发JavaScript中的全局触摸/点击事件

java - 为什么Java不允许在类外初始化变量或常量?