hashmap - 试图从 RwLock 返回引用, "borrowed value does not live long enough"错误

标签 hashmap rust borrow-checker rwlock

我最近一直在从事我的第一个 Rust 项目,但遇到了障碍。我正在使用 HashMapString 映射到 AtomicUsize 整数。 HashMapRwLock 保护以允许并发访问。我希望能够返回对 HashMap 中的 AtomicUsize 值的引用,但是如果我尝试在 RwLockWriteGuard 的生命周期之后将这些引用返回给调用者 我收到一个错误,提示 借用的值没有足够长的时间。我在下面复制了一个最小的例子,并将相同的例子放在 Rust Playground 上 here .

use std::collections::HashMap;
use std::sync::RwLock;
use std::sync::atomic::{AtomicUsize, Ordering};

struct Bar {
    val: AtomicUsize
}

impl Bar {
    pub fn new() -> Self {
        Bar { val: AtomicUsize::new(0) }
    }
}

struct Foo {
    map: RwLock<HashMap<String, Bar>>
}


impl Foo {
    pub fn get(&self, key: String) -> &Bar {
        self.map.write().unwrap().entry(key).or_insert(Bar::new())
    }
}

fn main() {
    let foo = Foo {map: RwLock::new(HashMap::new())};
    let bar = foo.get("key".to_string());
}

我得到的错误发生在线路上:

self.map.write().unwrap().entry(key).or_insert(Bar::new())

而且是因为借来的值不够长寿。我读过其他一些讨论这个错误的帖子,这个 one特别是特别相关。读完之后,我可以了解到从互斥体返回的值的生命周期必须小于互斥体的生命周期,这似乎完全排除了我正在尝试做的事情。我明白为什么这应该是不可能的,因为如果我们有一个指向 Hashmap 的指针,而另一个将值插入到互斥锁中导致它被调整大小,那么我们将有一个悬空指针。

那么,我的问题是双重的。首先,我只是很好奇我是否正确理解了问题,或者是否还有其他原因导致我被禁止做我想做的事情?我的第二个问题是,如果没有 Box 原子整数并将它们存储在 HashMap 中,是否有另一种方法可以完成我正在尝试做的事情?这种方法似乎对我有用,因为我们可以返回一个指向始终有效的 Boxed 值的指针。然而,这种方法似乎效率低下,因为它需要额外的指针间接层和额外的分配。谢谢!

最佳答案

你是正确的,你不能返回对比 MutexGuard 还长的东西的引用,因为这可能会导致悬空指针。

不过,将内容包装在 Box 中也无济于事! Box 是一个拥有的指针,除了重定向之外,就引用生命周期而言,它的行为类似于包含的值。毕竟,如果您返回对它的引用,其他人可能会从 HashMap 中删除它并取消分配它。

根据你想用引用做什么,我可以想到几个选项:

  1. 不是将值Box,而是将它们包装在Arc 中。从 HashMap 获取数据时,您将克隆 Arc,多个引用可以同时存在。

  2. 您还可以将 MutexGuard 与引用一起返回;见this question ,如果您只想对值进行操作然后相对较快地删除引用,这会很好用。这将保持互斥量直到您完成它。

关于hashmap - 试图从 RwLock 返回引用, "borrowed value does not live long enough"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40299671/

相关文章:

rust - 借用的值活得不够长(BufReader lines() 到 String 的迭代器)

rust - 尝试从向量返回值时出现错误 "the trait Sized is not implemented"

rust - Cargo 无法解析 url 版本 0.5.7 的 Cargo.toml

rust - 为什么 Vec<T>::split_at_mut 为范围的其余部分借用向量?

javascript - 数组中的所有对总和为 10,具有平均/最佳 O(n) 运行时复杂度

hashmap - 库中的全局可变 HashMap

Java:hashmap 和 keyset() 的问题

java - 操作复杂的 HashMap

rust - 在类似 `zip` 的函数中借用检查器问题并带有回调

rust - 从 HashMap 或 Vec 返回引用会导致借用超出其所在范围?