I'm learning Rust and the chapter for structs gives an example of a struct without a ;
at the end. It compiles but I have no idea why this is allowed.
fn main() {
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
}
... same question goes for functions, actually.
As Shepmaster said in the comment, the "reason" is that Rust defines so. Here I will explain the rules behind it.
Basically you can omit ;
when it ends with }
. This will answer your question.
However, there are a number of exceptions to the rule:
{}
appears indirectlyThe rule above doesn't apply when {}
appears indirectly, like
use std::io::{self, Read, Write}; // Here }; appears
or
let x = if cond {
1
} else {
2
}; // Here }; appears
In this case, {}
isn't a direct part of use
/let
. So in this case you need ;
.
Items are things which you can also place outside of functions. That is, one of extern crate
, use
, mod
, struct
, enum
, union
, type
, trait
, impl
, fn
, static
, const
, extern
, and macros.
You can place items either outside of functions or in a function. However, There is a difference between them:
;
when unnecessary.;
there. This is basically because the ;
itself is an empty statement.Example:
struct A {} // You can't place ; here
fn main() {
struct B {} // You can omit ; here
struct C {}; // You can also place ; here
}
You have to omit ;
if
let
aren't expressions), andExample:
fn f() -> i32 {
let x = 1;
x + x // You want to return x + x, so you can't place `;` here
}
if
, if let
, match
, loop
, while
, while let
, for
, unsafe
, and bare {}
ends with }
, so you can omit ;
after them. However, there is a slight effect if you place ;
here.
Example:
fn f(x: i32) -> i32 {
if x < 10 {
10
} else {
20
}; // If you remove ; here, then you will see a compile error.
42
}
In most cases, you don't have to place ;
here; instead you may have to place ;
in the blocks.
fn f(x: i32) -> i32 {
if x < 10 {
10;
} else {
20;
}
42
}
In statement positions, you can write three different kinds of macros:
some_macro!()
/some_macro![]
: this isn't in fact a statement macro; instead, this is a mere expression macro. It can't expand to items or let
.some_macro!{}
: this expands to zero or more statements.some_macro!();
/some_macro![];
/some_macro!{};
: this also expands to zero or more statements; however, there is a very minor difference: ;
is added to the last expanded statement.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