【发布时间】:2016-06-28 11:17:02
【问题描述】:
在 Rust 中为 HashMap 而不是 HashSet 提供 iter_mut 函数的设计原理是什么?
自己动手会不会是失礼(假设甚至可以做到)?
有一个可以缓解引起的情况
X的先前借用发生在这里;不可变借用防止X的后续移动或可变借用直到借用结束
示例
An extremely convoluted example (Gist) 没有说明为什么参数传递是这样的。有一个简短的评论来解释痛点:
use std::collections::HashSet;
fn derp(v: i32, unprocessed: &mut HashSet<i32>) {
if unprocessed.contains(&v) {
// Pretend that v has been processed
unprocessed.remove(&v);
}
}
fn herp(v: i32) {
let mut unprocessed: HashSet<i32> = HashSet::new();
unprocessed.insert(v);
// I need to iterate over the unprocessed values
while let Some(u) = unprocessed.iter().next() {
// And them pass them mutably to another function
// as I will process the values inside derp and
// remove them from the set.
//
// This is an extremely convoluted example but
// I need for derp to be a separate function
// as I will employ recursion there, as it is
// much more succinct than an iterative version.
derp(*u, &mut unprocessed);
}
}
fn main() {
println!("Hello, world!");
herp(10);
}
声明
while let Some(u) = unprocessed.iter().next() {
是一个不可变的借用,因此
derp(*u, &mut unprocessed);
是不可能的,因为未处理的不能可变地借用。在 while 循环结束之前,不可变借用不会结束。
我曾尝试使用this as reference 并最终试图通过各种赋值排列、括起来的大括号来欺骗借用检查器,但由于预期表达式的耦合,问题仍然存在。
【问题讨论】:
-
注意
while let Some(u) = unprocessed.iter().next()等价于for u in &unprocessed -
你这里还有一个问题:你不能在迭代
unprocessed时可变地借用它/持有对它的引用。为什么不简单地使用循环 consumeunprocessed并简化您的程序逻辑?
标签: rust standard-library idioms