:#/ GSLF Journal
← :#/ GSLF Journal

Rustlers Atom 1.1 - Expressions vs Statements

<figure class="video" style="margin:0;">
<div style="position:relative;width:100%;padding-bottom:56.25%;height:0;overflow:hidden;">
<iframe src="https://www.youtube.com/embed/TPqFcpbS0?si=fnHIgD2174Qa1Dme"
title="YouTube video player"
style="position:absolute;top:0;left:0;width:100%;height:100%;border:0;"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen></iframe>
</div>
</figure>

In Rust, the distinction between expressions and statements is a core concept that shapes the entire language.

  • A statement is an instruction that performs an action but does not return a value. Statements almost always end with a semicolon ;. For example, creating a variable with let is a statement.
  • An expression evaluates to and produces a value. Most of Rust code is made of expressions: a math operation (5 + 6), a function call, or even a code block {}.

The crucial difference lies in the semicolon. Adding a ; to the end of an expression turns it into a statement, suppressing its return value and making it return a special empty value called the unit type, written as ().

This design allows for very concise and elegant code. For instance, an if-else block is an expression, meaning its result can be directly assigned to a variable.

let condition = true;
// The entire if-else block is an expression that returns a value
let number = if condition { 5 } else { 6 }; // `number` is now 5

println!("The number is: {}", number);

The same principle applies to functions. The last expression in a function's body, if it is not followed by a semicolon, automatically becomes its return value. The return keyword is therefore often optional, used mainly for early returns.

fn add_one(x: i32) -> i32 {
    x + 1 // No semicolon here!
          // This is the function's return value.
}

In short: if you see a ;, you're performing an action without producing a value. If it's missing (at the end of a block or function), you're evaluating and returning a result. Understanding this duality is key to writing natural, idiomatic Rust.