在Rust中,从if else条件语句中分配值的惯用方式

47

在Rust中,创建或分配多个对象中的一个到变量的首选方式是什么?由于作用域的原因,似乎必须在if - else外部创建变量。我想到的两种方法都不太好。这里以字符串为例,这是其中一种方式,但它会生成一个未使用赋值的警告:

let mut s = String::new();
if condition {
    s = "first".to_string();
} else {
    s = "second".to_string();
}

另一种选择是这个:

let mut s = "second".to_string();
if condition {
    s = "first".to_string();
}

它更短,不会生成警告,但意味着s被赋值两次,并且如果condition为真,则"second".to_string()被运行但是浪费了。如果这些操作是昂贵的操作(可能带有副作用),则此方法不适合。

是否存在更好的替代方案?

2个回答

78
在Rust中,if/else块是一个表达式。也就是说,该块本身具有值,等同于执行的任何部分中的最后一个表达式。考虑到这一点,我会按照以下结构编写代码:
let s = if condition {
    "first"
} else {
    "second"
}.to_string();

1
谢谢 - 我想我之前看到过这个提到,但没有意识到它的重要性。 - Bob
1
@Bob:ifmatch 是表达式这个事实真的大大减少了需要可变变量的情况,要全心接受它 :) - Matthieu M.
我见过这样的条件语句: if let p = fun() {} else {}在 if 条件语句中进行赋值的目的是什么? - rbansal
这如何推广到根据相同条件分配两个或更多变量?为每个分配重复 if 代码块肯定不是答案。 - Christoph90
3
使用元组:let (a, b) = if condition { ("first", 1) } else { ("second", 2) }; - Benjamin Lindley

3

提供另一个角度可能有助于加深对Benjamin答案中正在发生的事情的理解。

编译器所做的相同操作,只是用另一种方式进行了书写:

let s = String::from(if condition {
    "first"
} else {
    "second"
});


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