Reverse iterating over a &vec versus vec.iter()
Solution 1
If you're just looping over the Vec
, then &vec
is idiomatic. This works because &Vec<T>
implements IntoIterator
, which is what the for loop uses.
However if you want to call Iterator
methods such as rev
, filter
, etc., you need an actual Iterator
(since Vec
doesn't implement Iterator
, only IntoIterator
).
So this:
for x in &vec.rev() {
...
}
is equivalent to:
for x in (&vec.rev()).into_iter() {
...
}
i.e. there's no chance to use IntoIterator
before trying to call Iterator
methods.
Solution 2
This is just basic precedence of the &
operator. In the first case, each method is called in turn:
vec.iter().rev()
(vec.iter()).rev() // same
In the second case, the &
binds after all the methods:
&vec.rev()
&(vec.rev()) // same
Generally, use &vec
when you can, but when you need to use iterator adapter methods, use iter
or into_iter
.
Related videos on Youtube
HiDefender
Updated on May 13, 2020Comments
-
HiDefender almost 4 years
This works because
Iterator
implementsrev()
whereself
is aDoubleEndedIterator
:let vec: Vec<i32> = Vec::new(); for x in vec.iter().rev() { //Do stuff }
However, if I change
vec.iter().rev()
to&vec.rev()
it won't compile because:no method named `rev` found for type `std::vec::Vec<i32>` in the current scope
Furthermore:
the method `rev` exists but the following trait bounds were not satisfied: `std::vec::Vec<i32> : std::iter::Iterator`, `[i32] : std::iter::Iterator`
But doesn't a for loop implicitly call
IntoIterator
? Is&vec
orvec.iter()
considered idiomatic Rust?