18

A common way to assign multiple variables is often expressed in programming languages such as C or Python as:

a = b = c = value;

Is there an equivalent to this in Rust, or do you need to write it out?

a = value;
b = value;
c = value;

Apologies if this is obvious, but all my searches lead to Q&A regarding tuple assignment.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ideasman42
  • 42,413
  • 44
  • 197
  • 320

5 Answers5

21

No, there is no equivalent. Yes, you have to write multiple assignments, or write a macro which itself does multiple assignments.

DK.
  • 55,277
  • 5
  • 189
  • 162
15

You cannot chain the result of assignments together. However, you can assign multiple variables with a single statement.

In a let statement, you can bind multiple names by using an irrefutable pattern on the left side of the assignment:

let (a, b) = (1, 2);

(Since Rust 1.59, you can also have multiple values in the left side of any assignment, not just let statements.)

In order to assign the same value to multiple variables without repeating the value, you can use a slice pattern as the left-hand side of the assignment, and an array expression on the right side to repeat the value, if it implements Copy:

let value = 42;
let [a, b, c] = [value; 3]; // or: let [mut a, mut b, mut c] = ...
println!("{} {} {}", a, b, c); // prints: 42 42 42

(Playground)

Miles
  • 31,360
  • 7
  • 64
  • 74
3

Actually, you can totally do this!

let a @ b @ c = value;

This uses the @ syntax in patterns, which is used to bind a value to a variable, but keep pattern matching. So this binds value to a (by copy), and then continues to match the pattern b @ c, which binds value to b, and so on.

But please don't. This is confusing and of little to no benefit over writing multiple statements.

DreamConspiracy
  • 343
  • 2
  • 11
2

Using const generics:

fn main() {
    let [a, b, c] = fill_new_slice(1);
    dbg!(a, b, c);
}

fn fill_new_slice<T: Copy, const N: usize>(value: T) -> [T; N] {
    [value; N]
}
$ cargo run --quiet
[src/main.rs:3] a = 1
[src/main.rs:3] b = 1
[src/main.rs:3] c = 1
danfo
  • 21
  • 2
0

In Rust, the expression a = b = c = value; is the same to a = (b = (c = value));

And the (x = ...) returns (). Then, the first expression is an equivalent of the following:

c = value;
b = ();
a = ();

Note that the expression has a semicolon in the end, but if the expression were in the last line as a function's return like this a = b = c = value, the equivalente would be the following:

c = value;
b = ();
a = () // without the semicolon
Frank Moreno
  • 304
  • 1
  • 7
  • 2
    "And the `(x = ...)` returns the value of `x`": This is not correct; [assignment returns the unit type](https://doc.rust-lang.org/reference/expressions/operator-expr.html#assignment-expressions) (i.e. `()`). [Rust Playground example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20let%20mut%20a%3A%20i32%20%3D%201%3B%0A%20%20%20%20println!(%22%7B%3A%3F%7D%22%2C%20a)%3B%0A%20%20%20%20println!(%22%7B%3A%3F%7D%22%2C%20(a%20%3D%202))%3B%0A%20%20%20%20println!(%22%7B%3A%3F%7D%22%2C%20a)%3B%0A%7D) – Miles Jan 30 '21 at 01:49
  • You are right. My bad. I updated the answer. – Frank Moreno Feb 01 '21 at 00:51
  • "In Rust, the expression `a = b = c = value;` is the same to `a = (b = (c = value));`" note that it is true for (probably) all C-like languages; the important part is assignment returning `()`. – Chayim Friedman Jun 01 '22 at 04:34
  • @ChayimFriedman they are not the same in Rust – Frank Moreno Feb 21 '23 at 16:21