为什么 Rust 中的 for 循环可以遍历切片或迭代器,但不能遍历数组?

4
为什么Rust 1.44.0中的for循环可以迭代slice和iterator,但不能迭代数组呢?例如,下面的代码会出现错误:
循环遍历一个数组:
fn main() {
    let a = [1, 2, 3, 4, 5];

    for element in a {
        println!("element={}", element);
    }
}

error[E0277]: `[{integer}; 5]` is not an iterator
 --> main.rs:4:20
  |
4 |     for element in a {
  |                    ^ borrow the array with `&` or call `.iter()` on it to iterate over it
  |
  = help: the trait `std::iter::Iterator` is not implemented for `[{integer}; 5]`
  = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
  = note: required by `std::iter::IntoIterator::into_iter`

循环遍历一个切片(版本1):

fn main() {
    let a = &[1, 2, 3, 4, 5];

    for element in a {
        println!("element={}", element);
    }
}

element=1
element=2
element=3
element=4
element=5

循环遍历切片(第二版):

fn main() {
    let a = [1, 2, 3, 4, 5];

    for element in &a {
        println!("element={}", element);
    }
}

element=1
element=2
element=3
element=4
element=5

循环遍历数组迭代器:

fn main() {
    let a = [1, 2, 3, 4, 5];

    for element in a.iter() {
        println!("element={}", element);
    }
}

element=1
element=2
element=3
element=4
element=5

Rust也可以通过以下方式循环遍历向量:
fn main() {
    let v = vec![1, 2, 3, 4, 5];

    for element in v {
        println!("element={}", element);
    }
}

element=1
element=2
element=3
element=4
element=5
2个回答

12

编译器告诉你原因:因为数组不是迭代器。

这里有一个长期存在的问题需要实现数组的IntoIterator,然而添加这个功能将会破坏兼容性,生态系统中已知会出现问题,所以进展缓慢。

从Rust 1.51开始,你可以使用array::IntoIter

fn main() {
    let a = [1, 2, 3, 4, 5];

    for element in std::array::IntoIter::new(a) {
        println!("element={}", element);
    }
}

自Rust 1.53起,你可以使用IntoIterator,但作为特例,编译器将继续将array.into_iter()解析为(&array).into_iter()以保持向后兼容性。这包括for-循环展开。

自2021版起,此特例已被删除,数组迭代与任何其他类型一样正常工作。


那么数组切片实现了 IntoIterator 吗?这是如何工作的? - Derek Mahar
“借用”数组 a 如何将其转换为迭代器? - Derek Mahar
2
@Derek 和其他类型一样:&[T] 有一个 IntoIterator 的实现 - trent

11

从Rust 1.53.0开始,array的迭代行为已经发生变化。现在我们可以通过值来迭代数组:

for i in [1, 2, 3] {
    ...
}

这段代码现在是合法的。查看更多信息,请参见宣布 Rust 1.53.0


这是个好消息!这个变化终于让 Rust 数组的迭代与向量相匹配。 - Derek Mahar

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