collections - 如何从 RwLock-ed 结构中的 RefCell 内的 Hashmap 中删除项目

标签 collections rust mutable borrowing

我有一个结构:

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()CommunityContentsborrow_mut().insert(...) BtreeMap inside index.

我的问题是从 BtreeMap 中删除元素,给定 FriendID。我的粗略尝试是:

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

我得到错误不能借用为可变的。我已经尝试了各种让我的代码上面有点困惑的东西。

编辑:抱歉,我错过了问题中的 FriendDataData 结构。

最佳答案

在对您的示例代码中缺失的类型进行一些猜测后,我发现了两个错误:

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 ,这将返回 Option<&mut BTreeMap>你需要的:

let mut tmp = g.index.borrow_mut();
let mut a = tmp.get_mut(&friend_key);

关于collections - 如何从 RwLock-ed 结构中的 RefCell 内的 Hashmap 中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57350068/

相关文章:

java - collection.stream().skip().findFirst()的效率

rust - 我如何在 Rust 代码中表示 C 的 "unsigned negative"值?

rust - 如何安全地使用由唯一 ID 表示的外部数据?

python - python 关键字参数中列表的可变性(?)

rust - 当返回对范围外值的可变引用的不可变引用时,为什么在范围结束时丢弃可变引用?

java - Java中的所有列表是否都维护插入顺序

java - 我的 HashSet 包含(意义相同的)重复项!

magento - 如何在 Magento 中加入集合?

rust - 变量所有权在迭代之间如何工作?

rust - 函数调用后使用rust 的可变性要求