为什么for循环不需要可变迭代器?

15

如果我想手动消费一个迭代器,它必须是可变的:

let test = vec![1, 2, 3];
let mut test_mut = test.iter();
while let Some(val) = test_mut.next() {
    println!("{:?}", val);
}

但我可以用 for 循环轻松使用它,即使它是不可变的。

let test = vec![1, 2, 3];
let test_imm = test.iter();
for val in test_imm {
    println!("{:?}", val);
}

我认为这个方法可行是因为test_imm被移入了for循环的代码块中,所以test_imm不再能被外部代码块所使用,且在for循环之前它是(从外部代码块的视角来看)不可变的,然后在for循环之后也无法访问,所以这是可以的。

那么,我的理解正确吗?还需要进一步解释吗?

1个回答

12

完全正确。由于它已被移到for循环中,所以for循环现在拥有它并可以随意使用,包括"使它"可变。考虑这个类比的例子,我们似乎正在改变不可变的xs,但实际上是因为我们正在移动它,所以新所有者可以自由地对其进行任何操作,包括将其重新绑定为可变的:

let xs: Vec<i32> = vec![1, 2, 3];

fn append(v: Vec<i32>, x: i32) -> Vec<i32> {
    let mut my_v = v;
    my_v.push(x);
    my_v
}

let appended = append(xs, 4);

playground

注意,使用mut参数方便语法可以使函数更短:

fn append(mut v: Vec<i32>, x: i32) -> Vec<i32> {
    v.push(x);
    v
}

这在iter模块的文档中或多或少都有解释。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接