Skip to content

Files

Latest commit

 Cannot retrieve latest commit at this time.

History

History
183 lines (148 loc) · 4.75 KB

if-expr.md

File metadata and controls

183 lines (148 loc) · 4.75 KB

r[expr.if]

if and if let expressions

if expressions

r[expr.if.syntax]

Syntax
IfExpression :
   if Expressionexcept struct expression 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 expressions

r[expr.if.let.syntax]

Syntax
IfLetExpression :
   if let Pattern = Scrutineeexcept lazy boolean operator expression 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. 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 ) { .. }