Reputation: 34934
Since semicolons are apparently optional in Rust, why, if I do this:
fn fn1() -> i32 {
let a = 1
let b = 2
3
}
I get the error:
error: expected one of `.`, `;`, `?`, or an operator, found `let`
--> src/main.rs:3:9
|
2 | let a = 1
| - expected one of `.`, `;`, `?`, or an operator here
3 | let b = 2
| ^^^ unexpected token
Upvotes: 81
Views: 27779
Reputation: 645
Short answer, No, they are required except the last expression in a block of code (it mean the value of the last expression is the value of the entire block)
Upvotes: 0
Reputation: 3282
Semicolons are generally not optional, but there are a few situations where they are. Namely after control expressions like for
, if/else
, match
, etc.
fn main() {
let a: u32 = 5;
if 5 == a {
println!("Hello!");
}
if 5 == a {
println!("Hello!");
};
for x in "World".chars() {
println!("{}", x);
}
for x in "World".chars() {
println!("{}", x);
};
}
(There are situations where you do need to have or not have semicolons for these statements. If you're returning the value from within you can't have a semicolon, and if you're setting a variable to be the value from within you'll need a semicolon.)
Upvotes: 9
Reputation: 5417
They're not optional. Semicolons modify the behaviour of an expression statement so it should be a conscious decision whether you use them or not for a line of code.
Almost everything in Rust is an expression. An expression is something that returns a value. If you put a semicolon you are suppressing the result of this expression, which in most cases is what you want.
On the other hand, this means that if you end your function with an expression without a semicolon, the result of this last expression will be returned. The same can be applied for a block in a match
statement.
You can use expressions without semicolons anywhere else a value is expected.
For example:
let a = {
let inner = 2;
inner * inner
};
Here the expression inner * inner
does not end with a semicolon, so its value is not suppressed. Since it is the last expression in the block, its value will be returned and assigned to a
. If you put a semicolon on this same line, the value of inner * inner
won't be returned.
In your specific case, not suppressing the value of your let
statement doesn't make sense, and the compiler is rightly giving you an error for it. In fact, let
is not an expression.
Upvotes: 169