if and if let expressions
if和 if let表达式
commit: f8e76ee9368f498f7f044c719de68c7d95da9972
本章译文最后维护日期:2020-11-13
if expressions
if表达式
句法
IfExpression :
ifExpression排除结构体表达式 BlockExpression
(else( BlockExpression | IfExpression | IfLetExpression ) )?
if表达式是程序控制中的一个条件分支。if表达式的形式是一个条件表达式,紧跟一个相应的块,再后面是任意数量的 else if条件表达式和块,最后是一个可选的尾部 else块。条件表达式的类型必须是布尔型(bool)。如果条件表达式的求值结果为 true,则执行紧跟的块,并跳过后续的 else if块或 else块。如果条件表达式的求值结果为 false,则跳过紧跟的块,并按顺序求值后续的 else if条件表达式。如果所有 if条件表达式和 else if条件表达式的求值结果均为 false,则执行 else块。if表达式的求值结果就是所执行的块的返回值,或者如果没有块被求值那 if表达式的求值结果就是 ()。if表达式在所有情况下的类型必须一致。
# let x = 3;
if x == 4 {
println!("x is four");
} else if x == 3 {
println!("x is three");
} else {
println!("x is something else");
}
let y = if 12 * 15 > 150 {
"Bigger"
} else {
"Smaller"
};
assert_eq!(y, "Bigger");
if let expressions
if let表达式
句法
IfLetExpression :
ifletMatchArmPatterns=Expression除了结构体表达式和惰性布尔运算符表达式 BlockExpression
(else( BlockExpression | IfExpression | IfLetExpression ) )?
if let表达式在语义上类似于 if表达式,但是代替条件表达式的是一个关键字 let,再后面是一个模式、一个 = 和一个检验对象(scrutinee)表达式。如果检验对象表达式的值与模式匹配,则执行相应的块。否则,如果存在 else块,则继续处理后面的 else块。和 if表达式一样,if let表达式也可以有返回值,这个返回值是由被求值的块确定。
let dish = ("Ham", "Eggs");
// 此主体代码将被跳过,因为该模式被反驳
if let ("Bacon", b) = dish {
println!("Bacon is served with {}", b);
} else {
// 这个块将被执行。
println!("No bacon will be served");
}
// 此主体代码将被执行
if let ("Ham", b) = dish {
println!("Ham is served with {}", b);
}
if let _ = 5 {
println!("不可反驳型的模式总是会匹配成功的");
}
if表达式和 if let表达式能混合使用:
let x = Some(3);
let a = if let Some(1) = x {
1
} else if x == Some(2) {
2
} else if let Some(y) = x {
y
} else {
-1
};
assert_eq!(a, 3);
if let表达式等价于match表达式,例如:
if let PATS = EXPR {
/* body */
} else {
/*else */
}
is equivalent to
match EXPR {
PATS => { /* body */ },
_ => { /* else */ }, // 如果没有 else块,这相当于 `()`
}
可以使用操作符 | 指定多个模式。这与匹配(match)表达式中的 | 具有相同的语义:
enum E {
X(u8),
Y(u8),
Z(u8),
}
let v = E::Y(12);
if let E::X(n) | E::Y(n) = v {
assert_eq!(n, 12);
}
if let表达式不能是惰性布尔运算符表达式。使用惰性布尔运算符的效果是不明确的,因为 Rust 里一个新特性(if-let执行链(if-let chains)的实现-请参阅eRFC 2947)正被提上日程。当确实需要惰性布尔运算符表达式时,可以像下面一样使用圆括号来实现:
// Before...
if let PAT = EXPR && EXPR { .. }
// After...
if let PAT = ( EXPR && EXPR ) { .. }
// Before...
if let PAT = EXPR || EXPR { .. }
// After...
if let PAT = ( EXPR || EXPR ) { .. }