if
和 if let
表达式
if
表达式
语法
IfExpression :
if
表达式结构体表达式除外 块表达式
(else
( 块表达式 | IfExpression | IfLetExpression ) )?
if
表达式是程序控制中的条件分支。if
表达式的语法是一个条件操作数,后跟一个结果块,任意数量的 else if
条件和块,以及一个可选的尾随 else
块。条件操作数必须具有 布尔类型。如果条件操作数求值为 true
,则执行结果块,并跳过任何后续的 else if
或 else
块。如果条件操作数求值为 false
,则跳过结果块,并评估任何后续的 else if
条件。如果所有 if
和 else if
条件都求值为 false
,则执行任何 else
块。if
表达式的求值结果与执行的块的值相同,如果没有块被执行,则为 ()
。if
表达式在所有情况下都必须具有相同的类型。
#![allow(unused)] fn main() { 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
表达式
语法
IfLetExpression :
if
let
模式=
被检查者惰性布尔运算符表达式除外 块表达式
(else
( 块表达式 | IfExpression | IfLetExpression ) )?
if let
表达式在语义上类似于 if
表达式,但它期望使用关键字 let
,后跟一个模式,一个 =
和一个 被检查者 操作数,而不是条件操作数。如果被检查者的值与模式匹配,则将执行相应的块。否则,如果存在,则流程进行到后续的 else
块。与 if
表达式一样,if let
表达式的值由评估的块确定。
#![allow(unused)] fn main() { let dish = ("Ham", "Eggs"); // this body will be skipped because the pattern is refuted if let ("Bacon", b) = dish { println!("Bacon is served with {}", b); } else { // This block is evaluated instead. println!("No bacon will be served"); } // this body will execute if let ("Ham", b) = dish { println!("Ham is served with {}", b); } if let _ = 5 { println!("Irrefutable patterns are always true"); } }
if
和 if let
表达式可以混合使用
#![allow(unused)] fn main() { 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 */
}
等价于
match EXPR {
PATS => { /* body */ },
_ => { /* else */ }, // () if there is no else
}
可以使用 |
运算符指定多个模式。这与 match
表达式中 |
的语义相同
#![allow(unused)] fn main() { 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 链的实现 - 请参阅 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 ) { .. }