r[expr.if]
if
and if let
expressionsif
expressionsr[expr.if.syntax]
IfExpression -> `if` Expression _except [StructExprStruct]_ BlockExpression (`else` ( BlockExpression | IfExpression | IfLetExpression ) )?
r[expr.if.intro] An if
expression is a conditional branch in program control. The syntax of an if
expression is a condition operand, followed by a consequent block, any number of else if
conditions and blocks, and an optional trailing else
block.
r[expr.if.condition-bool] The condition operands must have the boolean type.
r[expr.if.condition-true] If a condition operand evaluates to true
, the consequent block is executed and any subsequent else if
or else
block is skipped.
r[expr.if.else-if] If a condition operand evaluates to false
, the consequent block is skipped and any subsequent else if
condition is evaluated.
r[expr.if.else] If all if
and else if
conditions evaluate to false
then any else
block is executed.
r[expr.if.result] An if expression evaluates to the same value as the executed block, or ()
if no block is evaluated.
r[expr.if.type] An if
expression must have the same type in all situations.
# 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");
r[expr.if.let]
if let
expressionsr[expr.if.let.syntax]
IfLetExpression -> `if` `let` Pattern `=` Scrutinee _except [LazyBooleanExpression]_ BlockExpression (`else` ( BlockExpression | IfExpression | IfLetExpression ) )?
r[expr.if.let.intro] An if let
expression is semantically similar to an if
expression but in place of a condition operand it expects the keyword let
followed by a pattern, an =
and a scrutinee operand.
r[expr.if.let.pattern] If the value of the scrutinee matches the pattern, the corresponding block will execute.
r[expr.if.let.else] Otherwise, flow proceeds to the following else
block if it exists.
r[expr.if.let.result] Like if
expressions, if let
expressions have a value determined by the block that is evaluated.
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"); }
r[expr.if.let.else-if] if
and if let
expressions can be intermixed:
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);
r[expr.if.let.desugaring] An if let
expression is equivalent to a match
expression as follows:
if let PATS = EXPR { /* body */ } else { /*else */ }
is equivalent to
match EXPR { PATS => { /* body */ }, _ => { /* else */ }, // () if there is no else }
r[expr.if.let.or-pattern] Multiple patterns may be specified with the |
operator. This has the same semantics as with |
in match
expressions:
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); }
r[expr.if.let.lazy-bool] The expression cannot be a [lazy boolean operator expression][expr.bool-logic]. Use of a lazy boolean operator is ambiguous with a planned feature change of the language (the implementation of if-let chains - see eRFC 2947). When lazy boolean operator expression is desired, this can be achieved by using parenthesis as below:
// Before... if let PAT = EXPR && EXPR { .. } // After... if let PAT = ( EXPR && EXPR ) { .. } // Before... if let PAT = EXPR || EXPR { .. } // After... if let PAT = ( EXPR || EXPR ) { .. }