#4 Functions and control flow
fn, if, loop, match
Defining functions
Functions are declared with the fn keyword. Rust uses snake_case for function names by convention:
fn greet(name: &str) {
println!("Hello, {name}!");
}
fn main() {
greet("Alice");
}Functions can be defined anywhere in the file — before or after main. Rust does not require forward declarations.
Parameters and return types
Every function parameter must have its type annotated. To return a value, declare the return type with ->:
fn add(a: i32, b: i32) -> i32 {
a + b // No semicolon = this is the return value
}
fn main() {
let result = add(3, 7);
println!("The sum of 3 and 7 is: {result}");
}Notice there is no semicolon on the last line of add. In Rust, the last expression in a function is implicitly returned. You can also use the return keyword for early returns.
if / else
Conditional logic works with if, else if, and else. The condition must be a bool — Rust does not automatically convert numbers to booleans:
let x = 5;
if x > 0 {
println!("x is positive");
} else if x < 0 {
println!("x is negative");
} else {
println!("x is zero");
}Since if is an expression in Rust, you can use it to assign a value:
let condition = true;
let number = if condition { 5 } else { 6 };
// number is 5Loops
Rust has three kinds of loops: loop, while, and for.
let mut counter = 0;
loop {
counter += 1;
if counter == 3 {
break; // Exit the loop
}
}
// counter is 3let mut count = 1;
while count <= 3 {
println!("Count: {count}");
count += 1;
}// Range
for i in 1..=3 {
println!("Count: {i}");
}
// Collection
let fruits = ["apple", "banana", "cherry"];
for fruit in fruits {
println!("Fruit: {fruit}");
}The for loop is the most common in Rust. The range 1..=3 includes 3 (inclusive), while 1..3 would exclude it.
The match expression
match is Rust's powerful pattern matching construct. It's like a switch statement but much more powerful:
let number = 1;
match number {
1 => println!("One"),
2 => println!("Two"),
3 => println!("Three"),
other => println!("Other number: {other}"),
}The match expression must be exhaustive — it must cover every possible value. The underscore _ or a variable name (like other) acts as a catch-all pattern.
Your turn
Try running the functions demo with cargo run and cargo check in the terminal below: