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 :
iflet模式 (Pattern)=被匹配值 (Scrutinee)(懒惰布尔运算符表达式除外) 块表达式 (BlockExpression)
(else( 块表达式 | IfExpression | IfLetExpression ) )?
一个 if let 表达式在语义上与 if 表达式相似,但它不是一个条件操作数,而是期望关键字 let,后跟一个模式,一个 = 和一个 被匹配值 (scrutinee) 操作数。
如果被匹配值 (scrutinee) 的值与模式匹配,则执行相应的块。
否则,如果存在后续的 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 ) { .. }