I'm writing an is_prime
function in Rust, and I was under the impression that simply writing true
was the equivalent of return true;
, but this is not the case in my function:
fn is_prime(number: i64) -> bool {
for i in 2i64..number {
if number % i == 0 && i != number {
false
}
}
true
}
This will give me the error:
error[E0308]: mismatched types
--> src/lib.rs:4:13
|
4 | false
| ^^^^^ expected (), found bool
|
= note: expected type `()`
found type `bool`
Replacing true
and false
with return true;
/ return false;
works, but why does using the previous not compile?
Rust is expression-oriented. In any block, the last expression inside it is the value of the block. Thus, for a function, the last value in the block is treated as a return value.
In other blocks, though, this is not the case—the last value is, after all, treated as the value of the block, not as a return value for the function.
Take the snippet in isolation with just a bit added for clarity:
This means that the outcome of the
if
statement as a whole isfalse
if the clause is true, and that value is then duly inserted into thehas_factor
variable. If the clause is not true, then theelse
clause will be evaluated. Given that there is no else clause, it is as thoughelse { }
had been written, which is equivalent toelse { () }
. This else block evaluates to()
, the unit type. Now we have a mismatch: is theif
block (and hence thehas_factor
variable) of the typebool
, as theif
block requires, or()
, as the [lack of] else block requires? This is where the error comes from.Summary: you can’t just omit the
return
keyword, because that’s not what the expression orientation means. At the end of a function, they boil down to the same thing and the sans-return
form should be preferred, but in other locations they are not equivalent andreturn
must be explicit.Final code: