# Iterators, Tuples, and References

#1

This is really just a request for an explanation. With the following code:

``````fn tuples() {
let mut vec = Vec::new();
vec.push((1, 2));
vec.push((2, 3));

let count = vec.iter().filter( | &&(_,s) | s > 2 ).count();

println!("tuples: {}", count);
}

fn simple() {
let mut vec = Vec::new();
vec.push(2);
vec.push(3);

let count = vec.iter().filter( | &s | *s > 2 ).count();

println!("simple: {}", count);
}

fn double() {
let mut vec = Vec::new();
vec.push(2);
vec.push(3);

let count = vec.iter().filter( | &&s | s > 2 ).count();

println!("double: {}", count);
}

fn main() {
tuples();
simple();
double();
}
``````

The tuples() function makes me think that references to the tuples where actually added to the vector since the filter() method in theory takes a reference to the object for the filtering, and I’m assuming && means a reference to a reference.

The simple() method demonstrates the “normal” filter function using the reference…but then double() is declaring “s” as a reference to a reference (I think)…but then I have no clue why s > 2 works there, I’d assume I would have to do **s > 2 instead…so maybe double ampersand is not a reference to a reference?

Anyone have the skinny on this?

#2

`vec.iter()` returns an iterator over references to the things in `vec`. `vec` has type `Vec<(i32, i32)>`, so `vec.iter()` iterates over `&(i32, i32)`. The closure passed to `filter` takes, as you’ve noted, a reference to the type being iterated over, aka `&&(i32, i32)` here.

The `&s` and `&&s` in the closure arguments aren’t declaring `s` to be any specific type (its type is fixed). They are rather destructuring the argument. `| &s| *s > 2` is equivalent to `|s| { let &s = s; *s > 2 }` - it’s binding `s` to the contents of the reference that is being passed as the argument to the closure. Likewise, `&&s` is binding `s` to the `i32` that’s being referenced by the reference that’s passed as the argument to the closure.

#3

Okay, thank you, that explains some stuff. like when I end up with &&(, ref s) to get a reference to the second element when my initial impulse would be to do &&(, &s), which doesn’t work.

So i’m assuming these two statements are equivalent, they are just changing which side of the assignment operation is doing the destructuring/dereferencing?

``````|s| { let &s = s; *s > 2 }
|s| { let s = *s; *s > 2 }``````

#4

Yep!

#5

Just to make more clear: the first variant (`let &s = s;`) is an assignment with destructuring (that is, "look inside a reference from `s` and bind it’s content into new `s`), while the second variant (`let s = *s;`) is an assignment with dereferencing ("dereference value of `s` and assign the value it was pointing to to the new `s`"). The effect is the same, as was explained, just the terminology is a little different.