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 if или else пропускаются.

Если какой-либо операнд условия вычисляется в false или какой-либо образец let не сопоставляется со своим рассматриваемым выражением, последующий блок пропускается, и оценивается любое последующее условие 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");
}

// `if` может использоваться как выражение.
let y = if 12 * 15 > 150 {
    "Bigger"
} else {
    "Smaller"
};
assert_eq!(y, "Bigger");
}

Образцы if let

Образцы let в условии if позволяют привязывать новые переменные в область видимости, когда образец успешно сопоставляется.

Следующие примеры иллюстрируют привязки с использованием образцов 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);
}
}

Цепочки условий

Несколько операндов условий могут быть разделены с помощью &&.

Подобно Ленивому логическому выражению &&, каждый операнд вычисляется слева направо до тех пор, пока операнд не вычислится как false или сопоставление let не завершится неудачей, в этом случае последующие операнды не вычисляются.

Привязки каждого образца помещаются в область видимости, чтобы быть доступными для следующего операнда условия и последующего блока.

Следующий пример демонстрирует цепочку нескольких выражений, смешивая привязки 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 Edition differences

До редакции 2024 года цепочки let не поддерживаются. То есть грамматика LetChain не разрешена в выражении if.