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
Semi-colons are required after all expressions in rust (even when braces are present). Technically here the `;` is for the `let`, which is a statement, not for the match expression within it. The braces are part of the match, not of the let. So the let doesn't end with a block, and thus requires a semicolon.
Semicolons are optional, in general -- but without them, the compiler will try to guess what two lines mean in succession, and won't always guess correctly. In this case, its seeing the (...) on line 4 as a function parameter list, and compiling as though the previous {...} is a function being called.
Even Google's summarized ES6 style guide continues to require semi-colons. There is a good reason. As developers we should know that when you remove a feature there will inevitably be users who relied on that feature to help them accomplish their task (in this case, we all program and write code :)).
The #define directive is used to define values or macros that are used by the preprocessor to manipulate the program source code before it is compiled. Because preprocessor definitions are substituted before the compiler acts on the source code, any errors that are introduced by #define are difficult to trace.
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.
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); }; }
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1bf94760dccae285a2bdc9c44e8f658a
(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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With