【发布时间】:2017-03-11 00:38:50
【问题描述】:
我最近一直在做我的第一个 Rust 项目,但遇到了障碍。我正在使用 HashMap 映射 Strings 到 AtomicUsize 整数。 HashMap 受RwLock 保护以允许并发访问。我希望能够在HashMap 中返回对AtomicUsize 值的引用,但是如果我尝试在RwLockWriteGuard 的生命周期之后将这些引用返回给调用者,我会收到borrowed value does not live long enough 的错误。我在下面复制了一个最小的示例,并将相同的示例放在 Rust 游乐场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 值的指针。然而,这种方法似乎效率低下,因为它需要额外的指针间接层和额外的分配。谢谢!
【问题讨论】:
-
除了调整地图大小之外,其他人还可以简单地删除您引用的条目。
-
你说得对!对于我的用例,我不需要删除密钥,但编译器当然不知道。
标签: hashmap rust borrow-checker rwlock