Type mismatch when returning from inside if statem

2020-04-20 12:48发布

问题:

The following code fails to compile:

fn testing() -> i32 {
    let x = 5;
    if x == 5 {
        5
    }
    6
}

with this error:

error E0308: mismatched types. (expected (), found integral variable)

If I put an explicit return in front of the 5, or if I put the 6 inside an else block, everything works fine. What exactly is Rust complaining about?

回答1:

In Rust, nearly everything is an expression, including if-else. if generates a value, but there is no value for the expression if the expression fails (i.e. x != 5). When putting the 6 into the else block, the if-else statement returns an integral (which will be an i32 due to the return type). You can suppress the statement's value with a semicolon.

return 5 (note, that there is no semicolon) is also a statement, which results in (). Now the if expression always returns (), which is fine.

Idiomatically you should prefer the else variant, so you can omit the return:

fn testing() -> i32 {
    let x = 5;
    if x == 5 {
        5
    } else {
        6
    }
}


回答2:

if-else is an assignable expression that has a type. Omitting else {} is equivalent to if { ... } else { () }. If you assign that value to a variable:

// would not compile
let result = if x == 5 {
    5
};

it is equivalent to writing:

let result = if x == 5 {
    5
} else {
    ()
};

Making the type of result either integer or unit, which is invalid.