Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Vec implement the Iterator trait?

Tags:

rust

What is the design reason for Vec not implementing the Iterator trait? Having to always call iter() on all vectors and slices makes for longer lines of code.

Example:

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

compared to Scala:

val rx = xs.zip(ys)
like image 617
sge Avatar asked Nov 06 '19 07:11

sge


People also ask

How do iterators work in Rust?

In Rust, iterators are lazy, meaning they have no effect until you call methods that consume the iterator to use it up. For example, the code in Listing 13-10 creates an iterator over the items in the vector v1 by calling the iter method defined on Vec<T> . This code by itself doesn't do anything useful.

How do you know if an iterator is empty in Rust?

You can make your iterator peekable and peek the first item; if it's None , then the iterator is empty.

What does collect () do in Rust?

collect() can take all the values in an Iterator 's stream and stick them into a Vec . And the map method is now generating Result<i32, &str> values, so everything lines up.


2 Answers

An iterator has an iteration state. It must know what will be the next element to give you.

So a vector by itself isn't an iterator, and the distinction is important. You can have two iterators over the same vector, for example, each with its specific iteration state.

But a vector can provide you an iterator, that's why it implements IntoIterator, which lets you write this:

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

Many functions take an IntoIterator when an iterator is needed, and that's the case for zip, which is why

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

can be replaced with

let rx = xs.iter().zip(ys);
like image 55
Denys Séguret Avatar answered Oct 05 '22 03:10

Denys Séguret


What is the design reason for Vec not implementing the Iterator trait?

Which of the three iterators should it implement? There are three different kinds of iterator you can get from a Vec:

  1. vec.iter() gives Iterator<Item = &T>,
  2. vec.iter_mut() gives Iterator<Item = &mut T> and modifies the vector and
  3. vec.into_iter() gives Iterator<Item = T> and consumes the vector in the process.

compared to Scala:

In Scala it does not implement Iterator directly either, because Iterator needs the next item pointer that the vector itself does not have. However since Scala does not have move semantics, it only has one way to create an iterator from a vector, so it can do the conversion implicitly. Rust has three methods, so it must ask you which one you want.

like image 36
Jan Hudec Avatar answered Oct 05 '22 03:10

Jan Hudec