4 ms·
As a Rust noob, what's the rhyme or reason for semicolons? I see the example: struct S {} but here the semicolon is required: type T = S; or you get
by ridiculous_fish 7y ago
As a Rust noob, what's the rhyme or reason for semicolons?
I see the example:
struct S {}
but here the semicolon is required:
type T = S;
or you get weird errors. It's hard to predict when a semicolon is required at least for type declarations, is there an underlying principle?
- kchamplewski 7y agoThey appear to be similar to the way most other languages like C and Java use semicolons, where a semicolon isn't required after a code block (generally denoted by squiggly brackets), but is required at the end of most (all?) other statements.
- Sharlin 7y agoThe most confusing thing ever is, of course, the fact that C struct/union and C++ class declarations do require a semicolon after the closing curly bracket. This is because type declarations are permitted to occur inline in certain contexts, notably as the type specifier in a variable declaration.
- lifthrasiir 7y agoEvery language item ends either with blocks (when a nested structure is required) or `;` (when it's not). They do not mix; if an item uses a block you don't need `;`. So `type` needs no more blocks and ends with `;`, while `struct S { ... }` doesn't need `;`. Completing an example, there is another form of `struct` that looks like `struct S(u32);` which do need `;` by the aforementioned logic. (The same logic applies to statements. You may think of an apparent exception like `{ println!("42"); 54 }`, but here `54` is an expression and you can't put a non-expression statement like `let x = 42` there without a semicolon.)
- dbaupp 7y agoAs others have said the principal is: no semicolons after things that use {}, semicolons after everything else.
- Setev 7y agoThis isn't quite true. Semi-colons are required after all expressions in rust (even when braces are present). e.g. `let x = match y { ... };`
- masklinn 7y agoTechnically 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.
- asdkhadsj 7y agoWeird, I thought it was just something like "If it's an expression, use a semicolon otherwise you're returning it". Yet everyone here is making a distinction between blocks and not-blocks. Is "my rule" better? Furthermore, if you say the semicolon is for the let I think it misleads people. Eg if you do `match foo { .. }`, with no let and no semicolon (which is what that rule would suggest), you're actually returning the value of the match. Same goes for a non-match block, too. Eg, `{ .. }` will return the contents. So if you want to prevent that, you use a semicolon. `{ .. };`. Am I missing something? Why are so many people describing it with the block vs semicolon thing?
- posixplz 7y agoYou’re correct. Other folks seem to be using non-Rust mental models for semicolons.
- masklinn 7y agoNo they're not, see steve's explanation above. Putting a semicolon after an expression makes it into a statement, which are unit-valued, which is why the expression's value gets suppressed. It's a subset of "statements not ending with blocks" (since an expression-statement doesn't take a statement-block even if the expression itself has one).
- deleted 7y ago[deleted]
- c03 7y agoSemicolons after statements. Optional after expressions.
- Myrmornis 7y agoOn the practical side, assuming you set up your editor to run rustfmt on save, then you don't have to think about it because rustfmt will insert delete semicolons if you get it wrong, and then you end up learning anyway.