3

我正在使用 Rust,并且HashMap为了方便起见,我想使用全局变量。然而,虽然可以HashMap使用lazy_staticand定义一个全局的、可变的Mutex,但在我的函数中定义的变量很难String具有与 gloabl 相同的生命周期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());
}

错误信息:

`user_email` does not live long enough
values in a scope are dropped in the opposite order they are defined
rustc(E0597)
4

1 回答 1

6

我试过直接插入 &str 并且效果很好。有没有办法将字符串转换为纯值?

这里的问题是您以错误的方式解决问题:&'static str基本上只适用于文字,因为它意味着“指向存在于其他地方但从未被收集的字符串的指针”('static意思是“永远存在”)。几乎唯一可能的选择是静态数据(存在于二进制文件本身中,因此只要程序运行就存在)或泄漏内存(这通常不是一个好主意)。

这里你想要的是你的地图自己存储字符串,当一个字符串从地图中删除时,它应该被收集。那就是String。这就是它的作用,也是它的用途。也许Cow<'static, str>在您混合使用静态数据和动态分配的数据的奇怪情况下,但这里似乎并非如此。

因此解决方法是:

lazy_static! {
    static ref USER_TOKEN_HASHMAP: Mutex<HashMap<String, String>> = Mutex::new(HashMap::new());
}

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, user_password);
}

顺便说一句,我建议不要使用:_前缀,_map这意味着您出于某种原因想要名为 / 的项目,但您不想使用它(未使用前缀为_的绑定不会被警告)。在这里它被积极使用,所以它不应该是前缀。

于 2021-01-13T08:41:43.883 回答