What is the exact definition of the for loop in Rust?
for-loop, iterator, reference, rust
Solution
First of all, here's a link to the definition of `for` in the reference.
To summarise, `B` is any expression which evaluates to something that can be converted into a value that implements the `Iterator<T>` trait, whilst `A` is a irrefutable pattern that binds values of type `T`.
In your specific case, `slice::iter` returns an `Iter<i32>`, which implements `Iterator<Item = &i32>`. That is, it doesn't yield `i32`s, it yields `&i32`s.
Thus, in both the first and second examples, `k` is actually binding to `&i32`s, not `i32`s. When you specified the type of the closure, you were actually specifying the wrong type. The reason the final example works is because `A` is a pattern, not a variable name. What `&k` is actually doing is "de-structuring" the `&i32`, binding the `i32` part to a variable named `k`.
The "irrefutable" part simply means that the pattern must always work. For example, you can't do `for Some(x) in thingy` where `thingy` implements `Iterator<Option<_>>`; `Some(x)` would not necessarily be valid for every element in the iterator; thus, it's a refutable pattern.
Problem
I'm coming from a C (and to a lesser extent, C++) background. I wrote the following code snippet: ``` fn main() { let my_array = [1, 2, 3]; let print_me = |j| println!("= {}", j); for k in my_array.iter() { print_me(k); } } ``` This compiled and ran as expected, but then I specified the type of the argument passed to the closure `print_me` thus: ``` fn main() { let my_array = [1, 2, 3]; let print_me = |j: i32| println!("= {}", j); for k in my_array.iter() { print_me(k); } } ``` I got a compilation error: ``` error[E0308]: mismatched types --> src/main.rs:6:22 | 6 | print_me(k); | ^ | | | expected i32, found &{integer} | help: consider dereferencing the borrow: `*k` | = note: expected type `i32` found type `&{integer}` ``` Now this confused me until I changed `k` to `&k` in the `for` statement, which worked fine: ``` fn main() { let my_array = [1, 2, 3]; let print_me = |j: i32| println!("= {}", j); for &k in my_array.iter() { print_me(k); } } ``` It seems that I misunderstood the `for` syntax itself -- or maybe the exact workings of an iterator -- or maybe the usage syntax of a reference vis-a-vis a pointer [which are related but distinct in C++]. In the construct `for A in B { C1; C2; ... Cn }`, what exactly are `A` and `B` supposed to be?