为什么Vec没有实现Iterator trait?

13
< p > Vec没有实现Iterator特质的设计原因是什么?每次都要在所有向量和切片上调用iter()会使代码变得更长。

例子:


例如:

let rx = xs.iter().zip(ys.iter());

与Scala相比:

val rx = xs.zip(ys)

2个回答

19

迭代器有一个迭代状态,必须知道下一个要给你的元素是什么。

所以一个向量本身不是一个迭代器,这种区别很重要。例如,您可以拥有两个迭代器,每个迭代器都具有其特定的迭代状态。

但是,向量可以为您提供迭代器,这就是为什么它实现了IntoIterator,它使您可以编写以下内容的原因:

let v = vec![1, 4];
for a in v {
    dbg!(a);
}

许多函数在需要迭代器时会使用 IntoIterator,这也适用于 zip,因此

let rx = xs.iter().zip(ys.iter());

可以替代为

let rx = xs.iter().zip(ys);

5
因为在 Rust 中,iter()into_iter()iter_mut() 之间的区别很重要。 - Sebastian Redl
是的,如果我们有一个可变的向量,那可能会很混乱。 - Denys Séguret
2
@DenysSéguret 你说得对。我建议只在不可变迭代(使用 iter)时启用它,并要求显式调用 iter_mut 进行可变迭代。 - Jmb
2
请注意,在 xs.iter().zip(ys) 中也可以使用相同的参数:你如何选择使用 ys.iter()ys.iter_mut() - Jmb
2
对于 ys,我们使用 into_iter。原因很简单:ys 被消耗了,所以其他迭代器类型没有意义。 - Cerberus
显示剩余7条评论

5

Vec为什么没有实现Iterator trait?

它应该实现哪种迭代器呢?从一个Vec中可以得到三种不同的迭代器:

  1. vec.iter()返回Iterator<Item = &T>,
  2. vec.iter_mut()返回Iterator<Item = &mut T>并修改向量和
  3. vec.into_iter()返回Iterator<Item = T>并在过程中使用向量。

与Scala相比:

在Scala中,它也没有直接实现Iterator,因为Iterator需要向量本身没有的下一个项指针。但是由于Scala没有移动语义,它只有一种从向量创建迭代器的方法,所以它可以隐式地进行转换。 Rust有三种方法,因此必须询问您想要哪种方法。


4
into_iter() 函数会消费掉这个向量; drain 不同的是它只会清空这个向量。 - trent

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