In Rust, a semicolon ends an expression statement. It also changes the expression’s value: an expression without a final semicolon can provide a value, while one with a semicolon returns the unit type, (). section 1.6 section 1.7
Use the final semicolon according to whether the surrounding code needs a value:
- Write 8 without a semicolon as the final expression of fn give_number() -> i32; the function returns 8. section 1.6
- Write 8; when the value is not needed; the expression produces (), Rust’s unit type, meaning “nothing.” section 1.6 section 3.1.3
- Apply the same rule to blocks: second_number + 9 returns a number, but second_number + 9; makes the block return (). section 1.7
- Remember that a function call can be the final expression without a semicolon when its unit result matches the surrounding function; adding the semicolon makes the intent clearer. section 3.1.3
Let the compiler identify the mismatch
This function promises an i32 but ends with 8;: fn give_number() -> i32 { 8; } Rust reports “expected i32, found ()” and suggests removing the semicolon. The corrected version is: fn give_number() -> i32 { 8 } You can also write return 8;, but the final expression is the usual concise form.
fn main() {
let my_number = {
let second_number = 8;
second_number + 9 #1
};
println!("My number is: {}", my_number);
}
A minimal block expression shows how a semicolon determines whether the block supplies a value to let my_number. section 1.7
