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

Modifying self in `iter_mut().map(..)`, aka mutable functional collection operations

如何转换成这样:

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

到使用 map 和闭包的单行操作?

我试过了:

a.iter_mut().map(|i| *i + 1).collect::<Vec<i32>>();

以上仅在我将其重新分配给 a 时才有效。为什么是这样? map 得到的是 a 的副本而不是可变引用?如果是这样,我怎样才能获得可变引用?

您的代码取消引用变量 (*i),然后将其加一。 原始值没有任何地方被改变。

完成您要求的最佳方法是使用 Iterator::for_each:

a.iter_mut().for_each(|i| *i += 1);

这会得到一个可变引用的迭代器,指向向量中的数字。对于每个项目,它取消引用引用然后递增它。

您可以使用 mapcollect,但这样做不符合习惯并且可能造成浪费。这使用 map 作为改变 原始值 的副作用。赋值的 "return value" 是单元类型 () - 一个空元组。我们使用 collect::<Vec<()>> 来强制 Iterator 适配器进行迭代。最后一位 ::<...> 称为 turbofish 并允许我们向 collect 调用提供 类型参数 ,通知它使用什么类型,因为没有其他东西会限制 return 类型。:

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

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

a.iter_mut().map(|i| *i += 1).count();

一样,使用 for 循环更为惯用:

for i in &mut a {
    *i += 1;
}