【问题标题】:Lifetime issue with a lazy_static mutable variablelazy_static 可变变量的终身问题
【发布时间】:2017-05-28 13:41:27
【问题描述】:

我使用lazy_static 在内存中保留HashMap。我使用两种方法添加和获取元素,但我在生命周期方面遇到了一些问题。

这是我的代码:

#[macro_use]
extern crate lazy_static;

use std::sync::Mutex;
use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: Mutex<HashMap<String, Foo>> = Mutex::new({
        let mut m = HashMap::new();
        m.insert("one".to_string(), Foo{param1:"foo1".to_string(),    param2:"foo2".to_string()} );
        m.insert("two".to_string(), Foo{param1:"bar1".to_string(), param2:"bar2".to_string()});
        m
    });
}

pub struct Foo{
    param1: String,
    param2: String,
}

pub fn ins_val(name: String, f: Foo){
    HASHMAP.lock().unwrap().insert(name, f);
}

pub fn get_val(k: &str) -> Option<&Foo>{
    HASHMAP.lock().unwrap().get(k)
}

这是错误:

HASHMAP.lock().unwrap().get(k) 
^^^^^^^^^^^^^^^^^^^^^^^
reference must be valid for the anonymous lifetime #1 defined on the block

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    Rust 正确地防止了这里的错误。

    您的 get_val 函数正在尝试返回对 HASHMAP 的引用,但除非您继续保持锁定,否则这是不安全的,否则其他人可能会来修改您脚下的地图。

    您需要保持锁定直到您返回值(通过将互斥保护与值一起返回;例如使用来自owning_ref 板条箱的MutexGuardRef),或者复制值而不是返回引用:

    pub fn get_val(k: &str) -> Option<Foo> {
        HASHMAP.lock().unwrap().get(k).cloned()
    }
    

    有了这个实现Foo当然需要实现Clone

    【讨论】:

    • 另一种选择是更改接口以接受一个获取地图引用的闭包,它可以选择是否返回引用的副本,或者只是检查它。更多详情in this answer.
    • 请注意,您可以使用option.cloned() 作为option.map(Clone::clone) 的简写。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多