Iter() noob question

#![feature(core_intrinsics)]
fn print_type_of<T>(_: &T) {
    println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}

fn main() {
    let v = vec![1];
    for &item in v.iter()   
    {
        print_type_of(&item);   //the type of item is i32
    }

    for item in v.iter()
    {
        print_type_of(&item);    //the type of itme is &i32
    }
}

&item really confuse me,
item is a reference to i32,what is &item!?
why not use
for *item in v.iter() //item is a reference to i32,so dereference here make more scene
{
//snip
}

The &item part in for loop is a pattern. It means that you describe the shape of the value being taken from the iterator.

In the first case, you essentially say: "I'm taking a reference to some item". So, the item is copied out of this reference.
In the second case, you take an item as-is - and as the iterator yields references, that's what you get.

Note also, that the patterns are not restricted only to references. Check this (playground):

#![feature(core_intrinsics)]
fn print_type_of<T>(_: &T) {
    println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}

struct Wrapper(i32);

fn main() {
    let v: Vec<_> = vec![Wrapper(1)];
    for item in v.iter()
    {
        print_type_of(&item);   //the type of item is &Wrapper
    }
    for &Wrapper(item) in v.iter()
    {
        print_type_of(&item);   //the type of item is i32
    }
}
2 Likes

Not the OP but to clarify further:

item in the above loop is a reference and when we do (inside the loop)

Should &item not expand to &(&item) implying a reference to the reference?

     ↳ &item because (for x in iter) will return a reference

Note that the print_type_of accepts the reference to the type parameter T, but prints type of T itself. So, we're passing &&i32, &T is equal to &&i32, and so T is &i32.

2 Likes