在Rust中如何在一行中将单个值分配给多个变量?

19

在编程语言中,通常用以下方式来分配多个变量,比如C或Python:

a = b = c = value;

在 Rust 中是否有相对应的东西,还是需要手写实现?

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

如果这很显然,那么我很抱歉,但我的所有搜索都指向了有关元组分配的问答。


1
我不相信有这样的事情。 - Veedrac
5个回答

23

没有等同的函数。是的,你需要编写多个赋值语句,或者编写一个宏,本身执行多个赋值语句。


18
这个决定背后的部分原因是所有权问题:a = b = c = Vec::new() 的结果会是什么? - Shepmaster
1
对于通过值进行复制的类型,它可能有效,但是我看到它为什么不太适合Rust。 - ideasman42

16

您不能将赋值的结果链接在一起。但是,您可以使用单个语句分配多个变量。

let语句中,您可以通过在赋值的左侧使用不可反驳的模式来绑定多个名称:

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

(自 Rust 1.59 起, 您不仅可以在任何赋值语句的左侧使用 let 语句,还可以有多个值。)

为了将相同的值分配给多个变量而不重复该值,您可以使用 切片模式 作为赋值的左侧,并在右侧使用 数组表达式 重复该值,如果它实现了 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

(游乐场)


4
实际上,您完全可以做到这一点!
let a @ b @ c = value;

这里使用了模式中的@语法,用于将值绑定到变量并保持模式匹配。因此,它将value(通过复制)绑定到a,然后继续匹配模式b @ c,将value绑定到b,以此类推。
但请不要这样做。这会让人感到困惑,而且与编写多个语句相比几乎没有任何好处。

虽然看起来很混乱,但我现在故意写了一段非常混乱的代码,用于一个笑话项目,这是一个很好的补充,所以谢谢你发布这个 :) - undefined

2
使用常量泛型
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

0
在 Rust 中,表达式 a = b = c = value; 等同于 a = (b = (c = value)); 而且 (x = ...) 返回 ()。因此,第一个表达式等同于以下内容:
c = value;
b = ();
a = ();

请注意,表达式末尾有一个分号,但如果表达式作为函数返回的最后一行,像这样a = b = c = value,则等效于以下内容:
c = value;
b = ();
a = () // without the semicolon

3
"而 (x = ...) 返回的是 x 的值" 这是不正确的;赋值返回单元类型 (即 ()). Rust Playground 示例" - Miles
你是对的。我的错。我更新了答案。 - Frank Moreno
在Rust中,表达式a = b = c = value;等同于a = (b = (c = value));。请注意,这对于(可能)所有类C语言都是正确的;重要的部分是赋值返回() - Chayim Friedman
@ChayimFriedman 在 Rust 中它们不是相同的。 - Frank Moreno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接