Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I destructure a tuple without binding the result to a new variable in a let/match/for statement?

Tags:

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?

like image 844
Cornstalks Avatar asked Dec 16 '15 05:12

Cornstalks


People also ask

What does the new Destructuring syntax allow you to do?

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

How do you swap variables in Destructuring assignment?

[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] .

How do you Destructure an object in TypeScript?

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.

Why do we use Destructuring in JavaScript?

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.


2 Answers

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.

like image 190
DK. Avatar answered Sep 20 '22 04:09

DK.


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:

  • How to swap two variables?
like image 39
Shepmaster Avatar answered Sep 19 '22 04:09

Shepmaster