lazy_static是一个非常流行的板条箱。几年前,对于某些任务,它没有更好的选择。但今天,还有什么理由选择lazy_static
更新的Once_cell或即将推出的LazyLock呢?
我想在一个项目中使用 Async MongoDB。
不想绕过客户端,因为它需要绕过多个任务和线程。所以我使用惰性静态保留了一个静态客户端。但是我不能在初始化块中使用 await。
我能做些什么来解决这个问题?
也欢迎在没有 lazy_static 的情况下完全不同地做这件事的建议。
use std::env;
use futures::stream::StreamExt;
use mongodb::{
bson::{doc, Bson},
options::ClientOptions,
Client,
};
lazy_static! {
static ref MONGO: Option<Client> = {
if let Ok(token) = env::var("MONGO_AUTH") {
if let Ok(client_options) = ClientOptions::parse(&token).await
^^^^^
{
if let Ok(client) = Client::with_options(client_options) {
return Some(client);
}
}
}
return None;
};
}
Run Code Online (Sandbox Code Playgroud) 我有一个大项目,我lazy_static
用来创建一个singleton
. 我认为lazy_static
crate 中存在错误(仅出现在大型项目中)或者我做错了什么,因为必须调用一次以创建单例的初始化函数被调用两次。
项目结构如下
Foo
|__foo-core
| |__src
| | |__lib.rs
| |__Cargo.toml
|
|__foo-high
| |__src
| | |__lib.rs
| |__Cargo.toml
|
|__src
| |__lib.rs
|__Cargo.toml
Run Code Online (Sandbox Code Playgroud)
foo/foo-core/src/lib.rs
pub mod my_file {
pub struct MyFile {
file: std::fs::File,
}
impl MyFile {
pub fn open(
path: &'static str,
) -> Result<MyFile, Box<dyn std::error::Error + Send + Sync>> {
let file_ = std::fs::File::create(path)?;
Ok(MyFile { file: file_ })
}
}
}
Run Code Online (Sandbox Code Playgroud)
foo/foo-high/src/lib.rs
mod high { …
Run Code Online (Sandbox Code Playgroud) 我正在使用 Rust,HashMap
为了方便起见,我想使用全局可变变量。然而,虽然可以HashMap
使用lazy_static
and定义一个全局的、可变的Mutex
,但String
我的函数中定义的变量很难与global具有相同的生命周期HashMap
。
我试过直接插入 &str 并且效果很好。有没有办法将字符串转换为纯值?
lazy_static! {
static ref USER_TOKEN_HASHMAP: Mutex<HashMap<&'static str, &'static str>> = {
let mut m = HashMap::new();
Mutex::new(m)
};
}
fn func() {
let mut _map = USER_TOKEN_HASHMAP.lock().unwrap();
let user_email = String::from("aaa");
let user_password = String::from("bbb");
_map.insert(user_email.as_str(), user_password.as_str());
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
`user_email` does not live long enough
values in a scope are dropped in the opposite order they are defined
rustc(E0597)
Run Code Online (Sandbox Code Playgroud) 文档指出,如果该类型具有析构函数,则不会调用它:https : //docs.rs/lazy_static/1.4.0/lazy_static/#semantics
那么我应该如何释放内存?
在 Rust 中,我试图声明一个自定义结构的静态实例。
因为默认情况下我不能分配 const 以外的其他值,所以我尝试使用lazy_static。
这是我的自定义结构:
pub struct MyStruct {
field1: String,
field2: String,
field3: u32
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试实例化它的方式:
lazy_static! {
static ref LATEST_STATE: MyStruct = {
field1: "".to_string(),
field2: "".to_string(),
field3: 0
};
}
Run Code Online (Sandbox Code Playgroud)
此代码无法编译并出现以下错误:
error: expected type, found `""``
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我是 Rust 新手。我正在尝试在库中创建一个静态变量,DATA
以便Vec<u8>
在编译库后对其进行初始化。然后我将该库包含在主代码中,希望能够DATA
直接使用而无需再次调用init_data()
。这是我尝试过的:
my_lib.rs:
use lazy_static::lazy_static;
pub fn init_data() -> Vec<u8> {
// some expensive calculations
}
lazy_static! {
pub static ref DATA: Vec<u8> = init_data(); // supposed to call init_data() only once during compilation
}
Run Code Online (Sandbox Code Playgroud)
主要.rs:
use my_lib::DATA;
call1(&DATA); // use DATA here without calling init_data()
call2(&DATA);
Run Code Online (Sandbox Code Playgroud)
但事实证明,init_data()
仍然是在调用main.rs
。这段代码有什么问题?
更新:正如 Ivan C 指出的那样,lazy_static
它不在编译时运行。那么,“预加载”数据的正确选择是什么?
我正在尝试使用静态 HashMap<String, Object> 来存储一些我想在未来全局使用和修改的数据。我发现声明这样一个全局映射的某种方法是使用 lazy_static 和互斥锁来安全地共享数据。但是,当我想将这些对象作为引用返回时,我遇到了一些所有权问题,就像我在上面的代码中所做的那样:
use std::error::Error;
use std::collections::HashMap;
use std::sync::Mutex;
use super::domain::{Session, SessionRepository}; // object and trait declaration
lazy_static! {
static ref REPOSITORY: Mutex<HashMap<String, Session>> = {
let mut repo = HashMap::new();
Mutex::new(repo)
};
}
impl SessionRepository for REPOSITORY {
fn find(cookie: &str) -> Result<&mut Session, Box<dyn Error>> {
let mut repo = REPOSITORY.lock()?;
if let Some(sess) = repo.get_mut(cookie) {
return Ok(sess);
}
Err("Not found".into())
}
}
Run Code Online (Sandbox Code Playgroud)
所以问题是:有没有办法正确地做到这一点?为了达到这种行为,我可以使用 Rust 中的任何设计模式吗?
非常感谢!
以下 Rust 代码,在 x86_64 平台编译。
#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;
lazy_static! {
static ref HASHMAP: HashMap<u32, &'static str> = {
let mut m = HashMap::new();
m.insert(0, "foo");
m.insert(1, "bar");
m.insert(2, "baz");
m
};
}
fn main() {
// First access to `HASHMAP` initializes it
println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
// Any further access to `HASHMAP` just returns the computed value
println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap());
}
Run Code Online (Sandbox Code Playgroud)
我使用readelf命令查看符号表中HASHMAP变量的大小:
readelf -sW target/debug/deps/section_test-4d7d6a03c56fdde3.o
Symbol table '.symtab' contains 590 …
Run Code Online (Sandbox Code Playgroud)