至少有两个原因不允许这样做:
-
您需要有两个并发的可变引用map
— 由迭代器中使用的一个for
循环和变量中的一map
打电话map.remove
.
-
您有对键和值的引用within尝试改变地图时的地图。如果允许您以任何方式修改地图,这些引用可能会失效,从而导致内存不安全。
Rust 的一个核心原则是别名 XOR 可变性。您可以对一个值有多个不可变引用,也可以对它有一个可变引用。
我不认为移动/借用适用于参考文献。
每种类型都遵循 Rust 的移动规则和可变别名。请让我们知道文档的哪一部分没有说明,以便我们解决这个问题。
为什么它试图移动引用?
这是由两部分组成的:
- 您只能有一个可变引用,因此可变引用不会实现Copy https://doc.rust-lang.org/std/marker/trait.Copy.html trait
-
for
loops 获取值并按值进行迭代 https://doc.rust-lang.org/std/iter/index.html#for-loops-and-intoiterator
你打电话时for (k, v) in map {}
,所有权map
被转移到 for 循环,现在消失了。
我会执行地图的不可变借用(&*map
)并迭代它。最后,我会把整个事情弄清楚:
fn do_it(map: &mut HashMap<String, String>) {
for (key, value) in &*map {
println!("{} / {}", key, value);
}
map.clear();
}
删除以字母“A”开头的键的每个值
I'd use HashMap::retain https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.retain:
fn do_it(map: &mut HashMap<String, String>) {
map.retain(|key, value| {
println!("{} / {}", key, value);
!key.starts_with("a")
})
}
这保证了key
and value
当地图实际修改时不再存在,因此他们本来拥有的任何借用现在都消失了。