Why is "&&" being used in closure arguments?
borrowing, reference, rust
Solution
`a` is of type `[i32; 3]`; an array of three `i32`s. `[i32; 3]` does not implement an `iter` method, but it does dereference into `&[i32]`. `&[i32]` implements an `iter` method which produces an iterator. This iterator implements `Iterator<Item=&i32>`.
It uses `&i32` rather than `i32` because the iterator has to work on arrays of any type, and not all types can be safely copied. So rather than restrict itself to copyable types, it iterates over the elements by reference rather than by value.
`find` is a method defined for all `Iterator`s. It lets you look at each element and return the one that matches the predicate. Problem: if the iterator produces non-copyable values, then passing the value into the predicate would make it impossible to return it from `find`. The value cannot be re-generated, since iterators are not (in general) rewindable or restartable. Thus, `find` has to pass the element to the predicate by-reference rather than by-value.
So, if you have an iterator that implements `Iterator<Item=T>`, then `Iterator::find` requires a predicate that takes a `&T` and returns a `bool`. `[i32]::iter` produces an iterator that implements `Iterator<Item=&i32>`. Thus, `Iterator::find` called on an array iterator requires a predicate that takes a `&&i32`. That is, it passes the predicate a pointer to a pointer to the element in question.
So if you were to write `a.iter().find(|x| ..)`, the type of `x` would be `&&i32`. This cannot be directly compared to the literal `i32` value `2`. There are several ways of fixing this. One is to explicitly dereference `x`: `a.iter().find(|x| **x == 2)`. The other is to use pattern matching to destructure the double reference: `a.iter().find(|&&x| x == 2)`. These two approaches are, in this case, doing exactly the same thing. [1]
As for why `Some(&2)` is used: because `a.iter()` is an iterator over `&i32`, not an iterator of `i32`. If you look at the documentation for `Iterator::find`, you'll see that for `Iterator<Item=T>`, it returns an `Option<T>`. Hence, in this case, it returns an `Option<&i32>`, so that's what you need to compare it against.
[1]: The differences only matter when you're talking about non-`Copy` types. For example, `|&&x| ..` wouldn't work on a `&&String`, because you'd have to be able to move the `String` out from behind the reference, and that's not allowed. However, `|x| **x ..` would work, because that is just reaching inside the reference without moving anything.
Problem
I have two questions regarding this example: ``` let a = [1, 2, 3]; assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); assert_eq!(a.iter().find(|&&x| x == 5), None); ``` Why is `&&x` used in the closure arguments rather than just `x`? I understand that `&` is passing a reference to an object, but what does using it twice mean? I don't understand what the documentation says: Because `find()` takes a reference, and many iterators iterate over references, this leads to a possibly confusing situation where the argument is a double reference. You can see this effect in the examples below, with `&&x`. Why is `Some(&2)` used rather than `Some(2)`?