我有两个 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
最佳答案
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();
关于rust - 如何使用从其他两个 HashMap 移动的值创建一个 HashMap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57649201/