问题描述
在 C 中,我可以使用索引以嵌套方式可变地迭代数组。在 Rust 中,我几乎可以使用索引来做同样的事情,但是如果我想使用迭代器而不是索引怎么办?
例如以下代码可以成功编译,因为两个借用都是不可变的:
let xs = [0,1,2];
for x in &xs {
for y in &xs {
println!("x={} y={}",*x,*y);
}
}
但是如果我想使用可变迭代器怎么办?
let mut xs = [0,2];
for x in &mut xs {
*x += 1;
for y in &mut xs {
*y += 1;
println!("x={} y={}",*y);
}
}
结果:
error[E0499]: cannot borrow `xs` as mutable more than once at a time
我理解需要引导对数据的写访问,但我也想知道一个有经验的 Rust 用户如何仅使用迭代器来实现这一点——假设索引只是为了教育目的。
解决方法
我理解需要对数据进行写入访问,但我也想知道有经验的 Rust 用户如何仅使用迭代器来实现这一点
他们不会,因为它不可行,至少不是原样:虽然对 while let
进行脱糖是一种常用方法,但它用于嵌套循环,您希望在其中推进相同的迭代器 在外循环和内循环中,它避免了跨越整个循环的独占借用的需要。
虽然在这里,您不想在不同的地方推进同一个迭代器,而是希望两个不同的变异迭代器到同一个集合。这意味着您对同一个集合有两个不同的可变引用(这是不允许的),并且您最终将有两个对集合中同一项目的可变引用(这也是不允许的)。
充其量,您可以使用内部可变性来解决问题,例如
let xs = [Cell::new(0),Cell::new(1),Cell::new(2)];
for x in &xs {
x.set(x.get() + 1);
for y in &xs {
y.set(y.get() + 1);
println!("x={} y={}",x.get(),y.get());
}
}
但我认为这不是通常的选择(回到索引会是,因为它不需要更改数据本身)。