ankush981
ankush981

Reputation: 5417

How can I destructure tuples into typed variables?

I'm trying to decompose a tuple into variables, and then cause an error by having one of the types mentioned incorrectly:

fn main() {
    let tup = (500, 6.4, 1);
    let (x: bool, y: f32, z: i16) = tup;
    println!("{}, {}, {}", x, y, z);
}

My idea was that the compiler would raise an error because x is given as bool but is being matched to 500. Surprisingly, it's the last statement where the compiler complains, saying that x, y, and z were not found in this scope:

I tried it another way:

fn main() {
    let tup = (500, 6.4, 1);
    let mut x: bool = true;
    let mut y: f32 = true;
    let mut z: i16 = true;
    (x, y, z) = tup;
    println!("{}, {}, {}", x, y, z);
}

This time, the compiler does raise the expected error, but it also says that the left-hand side of (x, y, z) = tup; isn't valid. Can someone explain what's happening?

Upvotes: 5

Views: 2928

Answers (2)

ljedrz
ljedrz

Reputation: 22173

You need to read the errors more carefully; the first case's very first one was:

error: expected one of `)`, `,`, or `@`, found `:`
 --> src/main.rs:3:11
  |
3 |     let (x: bool, y: f32, z: i16) = tup;
  |           ^ expected one of `)`, `,`, or `@` here

Which indicates that you can't provide types next to the variable names when you pattern match against a tuple. This is a parsing error which rendered that whole line invalid and caused x, y and z not to be found for the purposes of println!():

error[E0425]: cannot find value `x` in this scope
 --> src/main.rs:4:28
  |
4 |     println!("{}, {}, {}", x, y, z);
  |                            ^ not found in this scope

error[E0425]: cannot find value `y` in this scope
 --> src/main.rs:4:31
  |
4 |     println!("{}, {}, {}", x, y, z);
  |                               ^ not found in this scope

error[E0425]: cannot find value `z` in this scope
 --> src/main.rs:4:34
  |
4 |     println!("{}, {}, {}", x, y, z);
  |                                  ^ not found in this scope

As for the second case, there's a bunch of invalid assignments; y and z are numbers, but you try to assign bools to them; (x, y, z) = ... is also an invalid assignment - it doesn't pattern match (in Rustc versions < 1.59.0) unless it's within a let binding.

Upvotes: 5

Jmb
Jmb

Reputation: 23264

When doing tuple assignment, you should first specify all your variables, then all the types:

let (x, y, z): (bool, f32, i16) = tup;

gives the error you expect (playground)

Upvotes: 24

Related Questions