初始化传递给异步代码(例如 tokio 和 hyper)的 Rust 变量

Initializing a Rust variable passed to async code such as tokio and hyper

我有一个无法在编译时计算的值。它需要在任何应用程序代码 运行 之前计算,然后它只会在应用程序的整个生命周期中被读取。它还需要传递给执行程序,例如 tokiohyper 处理程序。

我怎样才能安全、惯用地创建这样的值,而不会造成不必要的性能损失?

理想情况下,我想做类似的事情:

#[tokio::main]
pub async fn main() {
    let db = init_db();

    // This uses a hyper server, passes db around
    // to tokio and hyper handlers, etc.
    run_app(&db);
}

您可以将数据包装在 Arc 中,这样您的数据就可以共享,并且它会一直存在,直到没有任何引用为止:

use tokio::prelude::*;
use tokio;
use std::sync::Arc;

async fn init_db() -> Arc<String> {
    Arc::new("Foo".to_string())
}

async fn run_app(data: Arc<String>) {
    for _ in 0..10 {
        println!("{}", data);
    }
}

#[tokio::main]
pub async fn main() {
    let db = init_db().await;

    // This uses a hyper server, passes db around
    // to tokio and hyper handlers, etc.
    run_app(db).await;
}

Playground version

您可以泄漏内存,使引用具有 'static 生命周期:

#[tokio::main]
pub async fn main() {
    let db = Box::leak(Box::new(init_db())) as &'static _;

    // This uses a hyper server, passes db around
    // to tokio and hyper handlers, etc.
    run_app(db);
}

If I create it with lazy_static!, it only gets computed when it's first accessed.

当惰性静态变量是 initialized:

时,有一个特定的函数来控制
use lazy_static::lazy_static; // 1.4.0

lazy_static! {
    static ref THING: String = String::from("a");
}

#[tokio::main]
pub async fn main() {
    lazy_static::initialize(&THING);
    run_app();
}