I'd like to destructure a tuple and assign part of the result to a new variable and assign another part of the result to an existing.
The following code illustrates the intent (it's a dumb example which results in an infinite loop printing [0]
):
fn main() { let mut list = &[0, 1, 2, 3][..]; while !list.is_empty() { let (head, list) = list.split_at(1); // An obvious workaround here is to introduce a new variable in the above // let statement, and then just assign it to list. println!("{:?}", head); } }
This code creates a new variable list
instead of reassigning it.
If I change the code to the following (to avoid the let
that introduces the new list
variable), it doesn't compile:
fn main() { let mut list = &[0, 1, 2, 3][..]; while !list.is_empty() { let head; (head, list) = list.split_at(1); println!("{:?}", head); } }
Compilation error:
error[E0070]: invalid left-hand side of assignment --> src/main.rs:5:22 | 5 | (head, list) = list.split_at(1); | ------------ ^ | | | cannot assign to this expression |
Is there a way to do this, or can destructuring only be used in let
, match
, and for
statements?
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
[a, b] = [b, a] is the destructuring assignment that swaps the variables a and b . At the first step, on the right side of the destructuring, a temporary array [b, a] (which evaluates to [2, 1] ) is created. Then the destructuring of the temporary array occurs: [a, b] = [2, 1] .
TypeScript casting a destructured object typeconst {firstname: string, age: number} = user; But this assigns the firstname variable to be string and the age variable to be called number . And when we introduce two of the same type, we are hit with an error since we are redefining a variable.
Destructuring is a JavaScript expression that allows us to extract data from arrays, objects, and maps and set them into new, distinct variables. Destructuring allows us to extract multiple properties, or items, from an array at a time.
No.
Destructuring is something you can only do with patterns; the left-hand side of an assignment is not a pattern, hence you can't destructure-and-assign.
See proto-RFC 372 (Destructuring assignment) which discusses the possibility of adding this feature.
Nightly Rust has feature(destructuring_assignment)
, which allows your original attempt to compile as-is:
#![feature(destructuring_assignment)] fn main() { let mut list = &[0, 1, 2, 3][..]; while !list.is_empty() { let head; (head, list) = list.split_at(1); println!("{:?}", head); } }
[0] [1] [2] [3]
However, I'd solve this using stable features like slice pattern matching, which avoids the need for the double check in split_at
and is_empty
:
fn main() { let mut list = &[0, 1, 2, 3][..]; while let [head, rest @ ..] = list { println!("{:?}", head); list = rest; } }
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With