我将Params
结构存储到SERVICES
单例中。使用get_params()
函数,我得到了Params
结构,但是我们必须克隆该结构的项才能使用它。
use lazy_static::lazy_static; // 1.4.0
use std::collections::HashMap;
use std::sync::Mutex;
#[derive(Debug)]
pub struct Params {
pub verbose: bool,
pub config_file: String,
}
lazy_static! {
#[derive(Debug)]
static ref SERVICES : Mutex<HashMap<&'static str, Params>> = Mutex::new( {
HashMap::new()
});
}
// OK
pub fn get_params() -> Params {
let serv_map = &SERVICES.lock().unwrap();
let cf: String = serv_map.get("params").unwrap().config_file.clone(); // clone here :(
let verbose = serv_map.get("params").unwrap().verbose;
Params {
verbose,
config_file: cf,
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let params = Params {
verbose: true,
config_file: "/user/toto.yml".to_string(),
};
{
SERVICES.lock().unwrap().insert("params", params);
}
let pp = get_params();
if pp.verbose {
dbg!(&pp.config_file, pp.verbose);
}
Ok(())
}
playground
我希望能够使用以下例程从单例中读取
Params
数据,而无需进行克隆:/*
Cannot compile
*/
pub fn get_params_ref<'lt>() -> &'lt Params {
let serv_map: &'lt HashMap<&'static str, Params> = &SERVICES.lock().unwrap();
let pp = &serv_map.get("params").unwrap();
pp
}
我得到:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:22:57
|
21 | pub fn get_params_ref<'lt>() -> &'lt Params {
| --- lifetime `'lt` defined here
22 | let serv_map: &'lt HashMap<&'static str, Params> = &SERVICES.lock().unwrap();
| ---------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'lt`
...
27 | }
| - temporary value is freed at the end of this statement
我知道为什么Rust无法编译此代码,但是有解决方案来获得对
Params
结构的不变引用吗?
最佳答案
如所写,您不能返回对SERVICES
元素的引用,因为编译器不知道这些元素的生存期:代码的另一部分可能会删除服务!
假设您只向SERVICES
添加元素,但从不删除任何元素,则因为它们是全局元素,所以可以对它们进行leak:
将Params
的定义更改为
#[derive(Debug)]
pub struct Params {
pub verbose: bool,
pub config_file: &'static str,
}
然后使用
config_file
初始化参数的Box::leak(String::from("foo").into_boxed_str())
。程序关闭时,操作系统将回收泄漏的内存。
也可以看看:
关于rust - 如何在不克隆的情况下获取对可变单例内部数据的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60840948/