if
和 if let
表达式
if
表达式
语法
If表达式 :
if
表达式不包括结构体表达式 块表达式
(else
( 块表达式 | If表达式 | IfLet表达式 ) )?
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
表达式
语法
IfLet表达式 :
if
let
模式=
被匹配项不包括惰性布尔运算符表达式 块表达式
(else
( 块表达式 | If表达式 | IfLet表达式 ) )?
if let
表达式在语义上类似于 if
表达式,但是在条件操作数的位置上,它期望关键字 let
后跟模式、等号和被匹配项 。如果被匹配项与模式匹配,则执行相应的代码块。
如果不匹配,存在 else
块时,则执行该块。
与 if
表达式类似, if let
表达式由执行的代码块的值确定。
#![allow(unused)] fn main() { let dish = ("Ham", "Eggs"); // 定义一个元组 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!("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 )。 当需要惰性布尔运算符表达式时,可以通过如下方式使用括号来实现:
// 之前...
if let PAT = EXPR && EXPR { .. }
// 之后...
if let PAT = ( EXPR && EXPR ) { .. }
// 之前...
if let PAT = EXPR || EXPR { .. }
// 之后...
if let PAT = ( EXPR || EXPR ) { .. }