Qubasa
Qubasa

Reputation: 183

tuple destructuring in for loops?

This compiles and outputs: i32

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

pub fn main() {
    let regions = [
        // From 0xe0000 to 0xfffff
        (0xe0000, 0xfffff),
    ];

    for (start, end) in &regions {
        print_type_of(start);
    }
}

This fails

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

pub fn main() {
    let regions = [
        // From 0xe0000 to 0xfffff
        (0xe0000, 0xfffff),
    ];

    // NEW
    for &(start, end) in &regions {
        print_type_of(start);
    }
}

with


error[E0308]: mismatched types
  --> test.rs:12:27
   |
12 |             print_type_of(start);
   |                           ^^^^^
   |                           |
   |                           expected reference, found integer
   |                           help: consider borrowing here: `&start`
   |
   = note: expected reference `&_`
                   found type `{integer}`

Why does for &(start, end) in &regions capture start and end as an int value but for (start, end) in &regions as a reference?

Upvotes: 0

Views: 1365

Answers (1)

WinterCicada
WinterCicada

Reputation: 96

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

pub fn main() {
    let &a = &32_i32;
    let b = 32_i32;
    print_type_of(&a);
    print_type_of(&b);
}

the output will be:

i32
i32

In the example, &a = &32_i32 is equivalent to b = 32_i32. The & in the left value will become the dereference of the right value, this is part of the Destructuring Pointers. Your code is equivalent to:

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

pub fn main() {
    let regions = [
        // From 0xe0000 to 0xfffff
        (0xe0000, 0xfffff)
    ];

    // NEW
    for (start, end) in regions {
        print_type_of(start);
    }
}

So (start, end) = (0xe0000, 0xfffff), start's type is i32.

Upvotes: 1

Related Questions