Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

if表达式

if 表达式的 语法格式 是一个或多个由 && 分隔的条件操作数序列,后跟一个结果块、任意数量的 else if 条件和块,以及一个可选的尾随 else 块。

条件操作数必须是具有 布尔类型表达式 或条件 let 匹配。

如果所有条件操作数求值结果均为 true,且所有 let 模式都成功匹配其 待匹配值,则执行结果块,并跳过任何后续的 else ifelse 块。

如果任何条件操作数求值为 false 或任何 let 模式未匹配其待匹配值,则跳过结果块,并对任何后续的 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");
}

// `if` 可以用作表达式。
let y = if 12 * 15 > 150 {
    "Bigger"
} else {
    "Smaller"
};
assert_eq!(y, "Bigger");
}

if let模式

if 条件中的 let 模式允许在模式匹配成功时将新变量绑定到作用域中。

以下示例演示了使用 let 模式进行的绑定:

#![allow(unused)]
fn main() {
let 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");
}
}

可以使用 | 运算符指定多个模式。这与 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);
}
}

条件链

多个条件操作数可以用 && 分隔。

类似于 && 惰性布尔表达式,每个操作数从左到右求值,直到某个操作数求值为 falselet 匹配失败,此时后续操作数将不再求值。

每个模式的绑定都会被放入作用域中,以便后续的条件操作数和结果块使用。

以下是一个链接多个表达式的示例,混合了 let 绑定和布尔表达式,并且表达式能够引用之前表达式中的模式绑定:

#![allow(unused)]
fn main() {
fn single() {
    let outer_opt = Some(Some(1i32));

    if let Some(inner_opt) = outer_opt
        && let Some(number) = inner_opt
        && number == 1
    {
        println!("Peek a boo");
    }
}
}

在不使用条件链的情况下,上述代码等效于:

#![allow(unused)]
fn main() {
fn nested() {
    let outer_opt = Some(Some(1i32));

    if let Some(inner_opt) = outer_opt {
        if let Some(number) = inner_opt {
            if number == 1 {
                println!("Peek a boo");
            }
        }
    }
}
}

如果任何条件操作数是 let 模式,由于与 let 待匹配值存在歧义和优先级关系,任何条件操作数都不能是 || 惰性布尔运算符表达式。如果需要 || 表达式,可以使用括号。例如:

#![allow(unused)]
fn main() {
let foo = Some(123);
let condition1 = true;
let condition2 = false;
// 此处需要括号。
if let Some(x) = foo && (condition1 || condition2) { /*...*/ }
}

2024 版次差异

在 2024 版次之前,不支持 let 链。也就是说,if 表达式中不允许使用 LetChain 语法。