如何从 RwLock-ed 结构中的 RefCell 内的 Hashmap 中删除项目
How to delete item from Hashmap inside a RefCell within an RwLock-ed Struct
我有一个结构:
pub struct CommunityContents {
pub friends: RefCell<HashMap<FriendID, FriendData>>,
pub index: RefCell<HashMap<u64, BTreeMap<FriendID, FriendData>>>,
pub authenticated: bool,
pub age: u64,
pub height: u64,
}
它受具有父结构的 RwLock 保护:
pub struct Community {
pub community_contents: RwLock<CommunityContents>,
}
pub struct FriendData {
pointer: Rc<Data>,
}
pub struct Data {
pub key: Key,
pub friend_ids: Vec<FriendID>,
}
我希望能够修改index
里面的数据。我可以毫无问题地将数据插入索引,执行 write()
到 CommunityContents
和 BtreeMap
的 borrow_mut().insert(…)
inside index
.
给定 FriendID
,我的问题是从 BtreeMap
中删除元素。我的粗略尝试是:
pub fn delete_family(community: &Self, friend_id: FriendID) {
//get community contents
let mut g = community.community_contents.write().expect("Lock is poisoned");
//get friend from inside friends name of community contents
let mut friend = g.friends.borrow_mut().get(&friend_id).unwrap().pointer.clone();
// get id attri
let mut friend_key = friend.key;
let mut a = g.index.borrow_mut().get(&friend_key);
let mut c = a.unwrap();
c.remove(&friend_id);
}
而且我收到错误信息 cannot borrow as mutable。我尝试了各种方法,这让我上面的代码有点乱。
编辑:抱歉,我错过了问题中的 FriendData
和 Data
结构。
根据您的示例代码对缺失的类型进行一些猜测后,我看到两个错误:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:37:21
|
37 | let mut a = g.index.borrow_mut().get(&friend_key);
| ^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
38 | let mut c = a.unwrap();
| - borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
error[E0596]: cannot borrow `*c` as mutable, as it is behind a `&` reference
--> src/lib.rs:39:9
|
38 | let mut c = a.unwrap();
| ----- help: consider changing this to be a mutable reference: `&mut std::collections::BTreeMap<u64, FriendData>`
39 | c.remove(&friend_key);
| ^ `c` is a `&` reference, so the data it refers to cannot be borrowed as mutable
可以按照建议修复第一个问题 - 使用新变量以确保临时值(在错误消息中带有下划线)足够长:
let mut tmp = g.index.borrow_mut();
let mut a = tmp.get(&friend_key);
现在借用的值 tmp
一直存在到函数的末尾,比需要从中借用的 a
还长。
第二个错误和建议可能更难理解。 a
是一个 Option<&BTreeMap>
但是在打开它之后你试图改变它,所以引用需要是可变的。 Option<&BTreeMap>
来自对 get
的调用,因此您需要找到一种方法来获取可变引用。您可以使用不同的方法 get_mut
来做到这一点,这将 return 您需要的 Option<&mut BTreeMap>
:
let mut tmp = g.index.borrow_mut();
let mut a = tmp.get_mut(&friend_key);
我有一个结构:
pub struct CommunityContents {
pub friends: RefCell<HashMap<FriendID, FriendData>>,
pub index: RefCell<HashMap<u64, BTreeMap<FriendID, FriendData>>>,
pub authenticated: bool,
pub age: u64,
pub height: u64,
}
它受具有父结构的 RwLock 保护:
pub struct Community {
pub community_contents: RwLock<CommunityContents>,
}
pub struct FriendData {
pointer: Rc<Data>,
}
pub struct Data {
pub key: Key,
pub friend_ids: Vec<FriendID>,
}
我希望能够修改index
里面的数据。我可以毫无问题地将数据插入索引,执行 write()
到 CommunityContents
和 BtreeMap
的 borrow_mut().insert(…)
inside index
.
给定 FriendID
,我的问题是从 BtreeMap
中删除元素。我的粗略尝试是:
pub fn delete_family(community: &Self, friend_id: FriendID) {
//get community contents
let mut g = community.community_contents.write().expect("Lock is poisoned");
//get friend from inside friends name of community contents
let mut friend = g.friends.borrow_mut().get(&friend_id).unwrap().pointer.clone();
// get id attri
let mut friend_key = friend.key;
let mut a = g.index.borrow_mut().get(&friend_key);
let mut c = a.unwrap();
c.remove(&friend_id);
}
而且我收到错误信息 cannot borrow as mutable。我尝试了各种方法,这让我上面的代码有点乱。
编辑:抱歉,我错过了问题中的 FriendData
和 Data
结构。
根据您的示例代码对缺失的类型进行一些猜测后,我看到两个错误:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:37:21
|
37 | let mut a = g.index.borrow_mut().get(&friend_key);
| ^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
38 | let mut c = a.unwrap();
| - borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
error[E0596]: cannot borrow `*c` as mutable, as it is behind a `&` reference
--> src/lib.rs:39:9
|
38 | let mut c = a.unwrap();
| ----- help: consider changing this to be a mutable reference: `&mut std::collections::BTreeMap<u64, FriendData>`
39 | c.remove(&friend_key);
| ^ `c` is a `&` reference, so the data it refers to cannot be borrowed as mutable
可以按照建议修复第一个问题 - 使用新变量以确保临时值(在错误消息中带有下划线)足够长:
let mut tmp = g.index.borrow_mut();
let mut a = tmp.get(&friend_key);
现在借用的值 tmp
一直存在到函数的末尾,比需要从中借用的 a
还长。
第二个错误和建议可能更难理解。 a
是一个 Option<&BTreeMap>
但是在打开它之后你试图改变它,所以引用需要是可变的。 Option<&BTreeMap>
来自对 get
的调用,因此您需要找到一种方法来获取可变引用。您可以使用不同的方法 get_mut
来做到这一点,这将 return 您需要的 Option<&mut BTreeMap>
:
let mut tmp = g.index.borrow_mut();
let mut a = tmp.get_mut(&friend_key);