rust - 如何使用从其他两个 HashMap 移动的值创建一个 HashMap?

标签 rust hashmap

我有两个 HashMap<&str, String>使用相同的 key ,我希望创建一个 HashMap在值组合的地方使用相同的键。我不想保留对前两个 HashMap 的引用s,但想移动 String到新的 HashMap .

use std::collections::HashMap;

#[derive(Debug)]
struct Contact {
    phone: String,
    address: String,
}

fn main() {
    let mut phones: HashMap<&str, String> = HashMap::new();
    phones.insert("Daniel", "798-1364".into());
    phones.insert("Ashley", "645-7689".into());
    phones.insert("Katie", "435-8291".into());
    phones.insert("Robert", "956-1745".into());

    let mut addresses: HashMap<&str, String> = HashMap::new();
    addresses.insert("Daniel", "12 A Street".into());
    addresses.insert("Ashley", "12 B Street".into());
    addresses.insert("Katie", "12 C Street".into());
    addresses.insert("Robert", "12 D Street".into());

    let contacts: HashMap<&str, Contact> = phones.keys().fold(HashMap::new(), |mut acc, value| {
        acc.entry(value).or_insert(Contact {
            phone: *phones.get(value).unwrap(),
            address: *addresses.get(value).unwrap(),
        });
        acc
    });

    println!("{:?}", contacts);
}

但是我有一个错误

error[E0507]: cannot move out of a shared reference
  --> src/main.rs:24:20
   |
24 |             phone: *phones.get(value).unwrap(),
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `std::string::String`, which does not implement the `Copy` trait

error[E0507]: cannot move out of a shared reference
  --> src/main.rs:25:22
   |
25 |             address: *addresses.get(value).unwrap(),
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `std::string::String`, which does not implement the `Copy` trait

Playground

最佳答案

HashMap::get 返回 Option<&V> ,即对 map 内部值的引用。您不能移出带有 * 的引用除非V工具 Copy .您需要一种不同的方法将值移出 map ,即 HashMap::remove (注意它返回 Option<V> )。

如果您尝试使用 remove 重写相同的算法,你会得到一个不同的错误:

    let contacts: HashMap<&str, Contact> = phones.keys().fold(HashMap::new(), |mut acc, value| {
        acc.entry(value).or_insert(Contact {
            phone: phones.remove(value).unwrap(),
            address: addresses.remove(value).unwrap(),
        });
        acc
    });
error[E0502]: cannot borrow `phones` as mutable because it is also borrowed as immutable
  --> src/main.rs:22:79
   |
22 |     let contacts: HashMap<&str, Contact> = phones.keys().fold(HashMap::new(), |mut acc, value| {
   |                                            ------        ----                 ^^^^^^^^^^^^^^^^ mutable borrow occurs here
   |                                            |             |
   |                                            |             immutable borrow later used by call
   |                                            immutable borrow occurs here
23 |         acc.entry(value).or_insert(Contact {
24 |             phone: phones.remove(value).unwrap(),
   |                    ------ second borrow occurs due to use of `phones` in closure

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.

此错误告诉您不能在迭代数据结构时改变数据结构,因为改变数据结构可能会使迭代器无效。 Sometimes you can solve this with interior mutability ,但在这种情况下,您不需要做任何类似的事情。只需调用 phones.into_iter()在迭代时将电话号码移出 map 。然后很容易使用 map创建(&str, Contact)元组,最后是 collect这一切都回到了HashMap .

    let contacts: HashMap<_, _> = phones
        .into_iter()
        .map(|(key, phone)| {
            (
                key,
                Contact {
                    phone,
                    address: addresses.remove(key).unwrap(),
                },
            )
        })
        .collect();

Playground

关于rust - 如何使用从其他两个 HashMap 移动的值创建一个 HashMap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57649201/

相关文章:

rust - 如何从默认方法返回特殊化的关联类型?

java - 删除方法不删除EmployeeStore的员工

rust - 如何将 Box<T> 转换为 &T?

rust - 如何查找tokio::sync::mpsc::Receiver是否已关闭?

Java Set of Maps hashCode 不正确?

java - 如何在java中的hashmap或hashtable中存储字节数组

java - 在 Java 中快速存储和检索点(相关 x 和 y)。列表与数组

java - 仅迭代 Map 的一部分

c - Rust 的 (void) 变量替代品

代理后使用rust , "error: no default toolchain configured"