Iterators and Ownership
Traits are like interfaces: they describe behavior (methods) for a type. The trait simply says that you can call next
until you get None
back:
You use this trait like this:
fn main() {
let v: Vec<i8> = vec![10, 20, 30];
let mut iter = v.iter();
println!("v[0]: {:?}", iter.next());
println!("v[1]: {:?}", iter.next());
println!("v[2]: {:?}", iter.next());
}
What is the type returned by the iterator? Test your answer here:
The Iterator
trait tells you how to iterate once you have created an iterator. The related trait IntoIterator
tells you how to create the iterator:
#![allow(unused)]
fn main() {
type Item;
type IntoIter: Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter;
}
}
The syntax here means that every implementation of IntoIterator
must declare two types:
IntoIter
: theIterator
type returned by theinto_iter
method.
Note that IntoIter
and Item
are linked: the iterator must have the same Item
type, which means that it returns
Now that we know both Iterator
and IntoIterator
, we can build for
loops. They call into_iter()
on an expression and iterates over the resulting iterator:
fn main() {
let v: Vec<String> = vec![String::from("foo"), String::from("bar")];
for word in &v {
println!("word: {word}");
}
for word in v {
println!("word: {word}");
}
What is the type of in each loop?
Experiment with the code above and then consult the documentation for impl IntoIterator for &Vec