在 `iter_mut().map(..)` 中修改 self,也就是可变函数集合操作

abj*_*ror 11 iterator rust

我如何转换这样的东西:

let mut a = vec![1, 2, 3, 4i32];
for i in a.iter_mut() {
    *i += 1;
}
Run Code Online (Sandbox Code Playgroud)

使用map和关闭的单行操作?

我试过:

a.iter_mut().map(|i| *i + 1).collect::<Vec<i32>>();
Run Code Online (Sandbox Code Playgroud)

以上仅在我将其重新分配给a. 为什么是这样?是否map正在获取副本a而不是可变引用?如果是这样,我怎样才能获得可变引用?

She*_*ter 14

您的代码取消对变量 ( *i) 的引用,然后向其添加一个。原始值在那里没有任何改变。

执行您要求的最佳方法是使用Iterator::for_each

a.iter_mut().for_each(|i| *i += 1);
Run Code Online (Sandbox Code Playgroud)

这将获得对向量中数字的可变引用的迭代器。对于每个项目,它取消引用引用,然后增加它。

您可以使用mapand collect,但这样做是不惯用的并且可能是浪费的。这map用于改变原始值的副作用。赋值的“返回值”是单元类型()——一个空元组。我们collect::<Vec<()>>用来强制迭代器适配器进行迭代。这最后一位::<...>被称为turbofish,使我们能够提供一个类型参数collect呼叫,通知它是什么类型的用途,如不出意外将限制返回类型:

let _ = a.iter_mut().map(|i| *i += 1).collect::<Vec<()>>();
Run Code Online (Sandbox Code Playgroud)

您还可以使用类似 的东西Iterator::count,它比创建 a 更轻巧Vec,但最终仍然不需要:

a.iter_mut().map(|i| *i += 1).count();
Run Code Online (Sandbox Code Playgroud)

正如Ry- 所说,使用for循环更为惯用:

for i in &mut a {
    *i += 1;
}
Run Code Online (Sandbox Code Playgroud)