ifif let 表达式

if 表达式

语法
IfExpression :
   if 表达式(结构体表达式除外) 块表达式
   (else ( 块表达式 | IfExpression | IfLetExpression ) )?

一个 if 表达式是程序控制流中的一个条件分支。if 表达式的语法是一个条件操作数,后跟一个结果块,任意数量的 else if 条件和块,以及一个可选的末尾 else 块。

条件操作数必须具有 布尔类型

如果条件操作数求值为 true,则执行结果块,并跳过任何后续的 else ifelse 块。

如果条件操作数求值为 false,则跳过结果块,并求值任何后续的 else if 条件。

如果所有 ifelse 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 模式 (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");
}
}

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