Выражения if
Syntax
IfExpression →
if Conditions BlockExpression
( else ( BlockExpression | IfExpression ) )?
Conditions →
Expressionexcept StructExpression
| LetChain
LetChain → LetChainCondition ( && LetChainCondition )*
LetChainCondition →
Expressionexcept ExcludedConditions
| OuterAttribute* let Pattern = Scrutineeexcept ExcludedConditions
ExcludedConditions →
StructExpression
| LazyBooleanExpression
| RangeExpr
| RangeFromExpr
| RangeInclusiveExpr
| AssignmentExpression
| CompoundAssignmentExpression
Синтаксис выражения 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.