rust 使用其他HashMap的值修改HashMap,这些HashMap的键是从第一个HashMap借用的

lymgl2op  于 2024-01-08  发布在  其他
关注(0)|答案(1)|浏览(148)

假设我有两个HashMapm1m2,它们具有相同的非Copy密钥集,只是m2的密钥是从m1借用的(说,m1具有String密钥,m2具有从m1借用的&str密钥).是否可以遍历m1并使用m2中的相应值更新其值?编译器认为,由于m2借用了(不可变地)从m1借用m1(比如说,通过iter_mut()get_mut())是不允许的。
下面是一个MVE,演示了两种迭代尝试:

use std::collections::HashMap;

fn main() {
    let mut m1 = HashMap::<_, _>::from_iter([("a".to_owned(), 1), ("b".to_owned(), 2)]);
    let m2 = m1
        .iter()
        .map(|(k, v)| (k.as_str(), v))
        .collect::<HashMap<_, _>>();

    for (k, v) in m1.iter_mut() {
        *v += m2[k.as_str()];
    }

    for (&k, &v) in m2.iter() {
        *m1.get_mut(k).unwrap() += v;
    }
}

个字符
我相信我尝试做的是合理的,因为修改HashMap的现有值不会导致它的任何键移动,所以m2m1的键的引用将保持有效。
我曾经考虑过使用Rc<String>键或者仅仅使用usize并将String存储在Vec中,但是我想知道是否有更简单的方法。

5f0d552i

5f0d552i1#

一般来说,编译器不允许&mut访问m1,因为你可以调用.clear()并销毁m2所借用的值。
对我来说,使用Rc作为键似乎是一个明智的解决方案。
另一个可以考虑的选择是对m1的值使用内部可变性类型(CellRefCell),这将允许您在&mut不访问m1的情况下改变它们。由于值是数字,Cell可能是一个很好的选择,因为它没有RefCell那样的引用计数开销。

相关问题