In the Rust Book there is an example of calling filter()
on an iterator:
for i in (1..100).filter(|&x| x % 2 == 0) {
println!("{}", i);
}
There is an explanation below but I'm having trouble understanding it:
This will print all of the even numbers between one and a hundred. (Note that because filter doesn't consume the elements that are being iterated over, it is passed a reference to each element, and thus the filter predicate uses the &x pattern to extract the integer itself.)
This, however does not work:
for i in (1..100).filter(|&x| *x % 2 == 0) {
println!("i={}", i);
}
Why is the argument to the closure a reference |&x|
, instead of |x|
? And what's the difference between using |&x|
and |x|
?
I understand that using a reference |&x|
is more efficient, but I'm puzzled by the fact that I didn't have to dereference the x
pointer by using *x
.
When used as a pattern match (and closure and function arguments are also pattern matches), the
&
binds to a reference, making the variable the dereferenced value.Has the error:
If you look at your error message for your case, it indicates that you can't dereference it, because it isn't a reference:
That's because you implicitly dereferenced it in the pattern match.
If this were true, then there would be no reason to use anything but references! Namely, references require extra indirection to get to the real data. There's some measurable cut-off point where passing items by value is more efficient than passing references to them.
And you do, in the form of a reference.
x
is a reference to (in this example) ani32
. However, the%
operator is provided by the traitRem
, which is implemented for all pairs of reference / value:This allows you to not need to explicitly dereference it.
It emphatically does not do that. In fact, it would be unsafe to do that, unless the iterated items implemented
Copy
(or potentiallyClone
, in which case it could also be expensive). This is why references are used as the closure argument.