Using & in for loop

Hello everyone.
Beginner question re idiomatic use of Rust reference in for loop.
The code in this chapter of The Book
[https://doc.rust-lang.org/book/ch10-00-generics.html](http://The Rust Book example)

fn largest(list: &[i32]) -> i32 {
    let mut largest = list[0];
    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

However, this version which I coded seems to produce same results as the Book version.

fn largest(list: &[i32]) -> i32 {
    let mut largest = list[0];

    for item in list {
        if *item > largest {
            largest = *item;
        }
    }

    largest
}

I would appreciate if someone please educate me which version should be used and why i should use one or the other. Perhaps they are equivalent and both are idiomatic Rust?

Many thanks in advance.

1 Like

For all intents and purposes both variants are the same, although there are some minor technical differences around ownership and lifetimes.

The first one (for &item in list) gets a &i32 from the list then uses pattern matching to bind the item variable to the i32 behind the reference. This logically emerges from the fact that you can use pattern matching almost everywhere you'd create a variable (e.g. let Point { x, y } = some_point). You may want to check out the Patterns chapter from The Rust Reference if you want more details/specifics.

The second version is simpler in that we're just binding item to a &i32, and then we dereference it like any other reference.

I personally prefer the latter, just because I think the & in for &item in list looks a bit strange and it might be easier to read for people less familiar with the idea of pattern matching... But to each their own :man_shrugging:

2 Likes

The biggest difference is that the first sample using pattern matching only works with Copy types. The latter sample works with both Copy and non-Copy types.

3 Likes

Wow, noted! Thank you.
This is quite subtle difference, at least for non-experts.
Is this behavioral difference documented anywhere?
Rust reference manual perhaps?

I'm sure it should talk about this if you find the documentation on patterns, and find the description of what an ampersand does in an pattern.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.