【发布时间】:2020-09-09 04:51:24
【问题描述】:
为了让我的代码更清晰易读,我将几个数据结构提取到一个单独的结构中:
struct S {
x: Vec<i32>,
y: HashSet<i32>,
z: Vec<i32>,
}
它只存在于一个方法调用中,它是子调用:
fn main() {
let mut w = S { x: vec![], y: HashSet::new(), z: vec![], };
do_part_of_the_work(&mut w);
}
fn do_part_of_the_work(w: &mut S) {
// 1. Works
for (index, &item) in w.x.iter().enumerate() {
if w.y.contains(&item) {
continue;
}
w.z[index] += 1;
}
// 2. Seems equivalent to 1. but doesn't work
for (index, &item) in w.x.iter().enumerate()
.filter(|&(_, &item)| !w.y.contains(&item)) {
w.z[index] += 1;
}
// 3. Seems equivalent to 2. and doesn't work either
for (index, &item) in w.iter_not_in_y() {
w.z[index] += 1;
}
}
impl S {
fn iter_not_in_y(&self) -> impl Iterator<Item = (usize, &i32)> {
self.x.iter().enumerate().filter(move |&(_, &item)| !self.y.contains(&item))
}
}
我实际上是在尝试以代码块3. 的形式执行代码块1. 所做的事情,而2. 作为一个不起作用的中间步骤,尽管这些看起来是等效的。如果S 的所有属性都是局部变量,那么这三个代码块似乎都可以工作。
在impl 内移动代码块也没有让我走远:
impl S {
fn doing_it_inside_the_struct(&mut self) {
// Doing 3. inside the struct instead, doesn't work either
for (index, &item) in self.iter_not_in_y() {
self.z[index] += 1;
}
}
}
为什么阻止2. 不起作用?不等于1.吗?是否可以通过选择不同的设计来避免这个问题?
【问题讨论】:
-
Borrow splititng 可能是相关的。
标签: rust iterator closures immutability borrow-checker