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 ) { .. }