Rust中几种迭代方式

https://juejin.cn/post/6985337507105734686#heading-6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fn main() {
let items = vec![11, 22, 33];

items.into_iter().for_each(|x| do_something(x));
}

fn do_something(n: i64) {
println!("Number {}", n)
}

fn main() {
let items = vec![11, 22, 33];

for x in items {
do_something(x);
}
}

fn do_something(n: i64) {
println!("Number {}", n)
}

这两种写法有何区别?哪种更好


这两个 Rust 程序的功能是相同的:它们都会遍历 items 向量中的每个元素,并对每一个元素调用 do_something 函数。它们的主要区别在于遍历向量的方式是不同的。

  • 在第一个程序中,你使用了 into_iter 方法和 for_each 方法。into_iter 会消费 items 向量,并返回一个可以用来遍历向量元素的迭代器。for_each 方法接收一个闭包,并对迭代器中的每个元素执行这个闭包。

  • 在第二个程序中,你使用了 for 循环来遍历向量中的每个元素。

这两种方式都是有效的,没有哪一种更好或更坏,它们只是风格和偏好的问题。for 循环的方式可能更为直观和易于理解,特别是对于初学者来说,因为这种方式在很多其他编程语言中都有类似的结构。而 into_iterfor_each 的方式则更符合函数式编程的风格,它可以使你的代码更为精简,但可能需要一些时间来熟悉。

还有一个值得注意的点是,into_iter 方法会消费 items 向量,这意味着在调用 into_iter 之后,你不能再使用 items 向量了。而 for 循环则不会消费 items 向量,所以在 for 循环之后,你还可以继续使用 items 向量。如果你需要在遍历向量后继续使用它,那么 for 循环可能是更好的选择。

总的来说,你可以根据你的需求和偏好来选择使用哪一种方式。


1
2
3
4
5
6
7
8
9
10
11
12
fn main() {
let items = ["a", "b", "c"];
for (i, x) in items.iter().enumerate() {
println!("Item {} = {}", i, x);
}
}
fn main() {
let items = ["a", "b", "c"];
items.iter().enumerate().for_each(|(i, x)| {
println!("Item {} = {}", i, x);
});
}

有何区别?

这两种写法在功能上是等价的,它们都使用了 Rust 的迭代器(Iterator)来遍历数组 items 中的元素,并打印每个元素及其索引。

主要的区别在于语法和代码风格上的差异。下面是对这两种写法的具体解释:

第一种写法:

1
2
3
4
5
6
fn main() {
let items = ["a", "b", "c"];
for (i, x) in items.iter().enumerate() {
println!("Item {} = {}", i, x);
}
}

在这种写法中,我们使用了 for 循环来遍历 items 数组的元素。通过调用 items.iter(),我们将数组转换为一个迭代器,然后使用 enumerate() 方法为每个元素生成一个包含索引和值的元组。在每次迭代中,元组的值被解构为 ix,分别表示索引和当前元素的值。最后,我们打印出索引和元素的值。

第二种写法:

1
2
3
4
5
6
fn main() {
let items = ["a", "b", "c"];
items.iter().enumerate().for_each(|(i, x)| {
println!("Item {} = {}", i, x);
});
}

这种写法使用了更紧凑的语法,使用 enumerate() 方法生成的迭代器直接调用 for_each() 方法,并接受一个闭包作为参数。闭包的参数是一个元组,包含索引和元素的值,然后在闭包体内打印出索引和元素的值。

总的来说,这两种写法在功能上是等价的,选择使用哪种写法取决于个人偏好和代码的可读性。第二种写法可能会更加简洁,而第一种写法可能更容易理解,特别是对于初学者来说。

文章目录