Reverse iterating over a &vec versus vec.iter()

12,930

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.

Share:
12,930

Related videos on Youtube

HiDefender
Author by

HiDefender

Updated on May 13, 2020

Comments

  • HiDefender
    HiDefender almost 4 years

    This works because Iterator implements rev() where self is a DoubleEndedIterator:

    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 or vec.iter() considered idiomatic Rust?