5.2 Expressions and Statements

Before diving into variables and data types, it's important to understand how Rust distinguishes between expressions and statements, a concept that differs slightly from C and C++.

5.2.1 Expressions

An expression is a piece of code that evaluates to a value. In Rust, almost everything is an expression, including literals, variable bindings, arithmetic operations, and even control flow constructs like if and match.

Examples of expressions:

5          // A literal expression, evaluates to 5
x + y      // An arithmetic expression
a > b      // A logical expression with a boolean result
if x > y { x } else { y }  // An if expression that returns a value

Note that these three code lines are not terminated with a semicolon, as adding one would convert the expression into a statement. Expressions by themselves do not form valid Rust code; they must be part of a larger construct, such as being assigned to a variable, passed to a function, or used within a control flow statement.

5.2.2 Statements

A statement is an instruction that performs an action but does not return a value. Statements include variable declarations, assignments, and expression statements (expressions followed by a semicolon).

Examples of statements:

#![allow(unused)]
fn main() {
let mut y = 0;
let x = 5;   // A variable declaration statement
y = x + 1;   // An assignment statement
}

Note: In Rust, assignments are statements that do not return a value, unlike in C where assignments are expressions that return the assigned value. This means you cannot use assignments within expressions in Rust, which prevents certain types of bugs.

In Rust, the semicolon ; is used to turn an expression into a statement by discarding its value. If you omit the semicolon at the end of an expression inside a function or block, it becomes the return value of that block.

Example:

#![allow(unused)]
fn main() {
let x = {
    let y = 3;
    y + 1  // No semicolon, this expression's value is returned
};
println!("The value of x is: {}", x);  // Outputs: The value of x is: 4
}

Understanding the distinction between expressions and statements is crucial in Rust because it affects how you write functions and control flow constructs.