Lesson 2
Expressions and functions
Tell an expression apart from a statement, type parameters, and choose between a final expression and explicit return.
Everything is worth something, until you add a semicolon
In “Variables, functions and control flow” you already called a function,
boost(), without naming why its last line had no ;. Here we formalize
that: what an expression is, what a statement is, and why that difference
decides whether your function compiles at all.
Rust builds almost everything out of expressions: a {} block, an if, a
function call — all of them produce a value. A statement, on the other hand,
produces nothing useful. Knowing which of the two you are looking at is the
foundation for reading — and writing — any Rust function with confidence.
You will go through four stations: functions and calls, typed parameters, expressions versus statements, and the two ways to return a value.
Exercise 01 · Fibonacci
Calculate the n-th Fibonacci number iteratively.
The starter already declares the signature with the correct return type. Complete the body with a loop that advances two accumulators each turn.
Objective
Complete fibonacci so it returns the n-th term of the sequence (0-indexed: fibonacci(0) == 0).
Implement
Replace `todo!` with a `for` loop that updates two variables each turn.
Function 01
Calculate Fibonacci iteratively
Use two mutable variables that each advance one position per loop turn, and return the first one when it finishes.
/// Returns the n-th Fibonacci number (0-indexed: fibonacci(0) == 0).
pub fn fibonacci(n: u32) -> u64 {
todo!("iterate n times, swapping a and b to compute the n-th Fibonacci number")
}Check
Run the visible cases and use the diagnostic to correct the code.
Visible tests
Modify the code before running the tests.
Help
View progressive hints or compare with the solution.
/// Returns the n-th Fibonacci number (0-indexed: fibonacci(0) == 0).
#[must_use]
pub fn fibonacci(n: u32) -> u64 {
let (mut a, mut b) = (0u64, 1u64);
for _ in 0..n {
let next = a + b;
a = b;
b = next;
}
a
}
// Playground entry point for this example.
fn main() {
println!("{}", fibonacci(10));
}Summary
fndeclares a function; calling it runs its body, defining it does not.- Each parameter has its own type; together with the return type they form the function’s signature.
- An expression produces a value; one extra
;turns it into a statement worth(). - An
E0308error withexpected T, found ()almost always means a stray;on the final expression. - A function’s final expression is its implicit return;
returnis for early exits. - The unit type
()takes up no memory: it is the default value when a function returns nothing useful.