Skip to content

Rust Functions

A function is a reusable, named block of code. Instead of writing the same steps over and over, you put them in a function once and call it whenever you need it. You’ve already been using one: main.

You define a function with fn, and you call it by writing its name followed by ():

fn greet() {
println!("Hello from a function!");
}
fn main() {
greet(); // call it
greet(); // call it again
}

Output:

Hello from a function!
Hello from a function!
▶ Try it Yourself

Functions become useful when you pass them data to work with. These inputs are called parameters. In Rust you must write the type of each parameter:

fn greet(name: &str) {
println!("Hello, {name}!");
}
fn main() {
greet("Alice");
greet("Bob");
}

Output:

Hello, Alice!
Hello, Bob!
▶ Try it Yourself

You can have as many parameters as you need, separated by commas:

fn describe(name: &str, age: u32) {
println!("{name} is {age} years old");
}
fn main() {
describe("Ferris", 10);
}

A function can hand a value back to whoever called it. You declare the return type after an arrow ->:

fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let sum = add(3, 4);
println!("3 + 4 = {sum}");
}

Output:

3 + 4 = 7
▶ Try it Yourself

Notice that a + b in the example above has no semicolon. This is a key Rust idea:

  • An expression without a semicolon is the value that gets returned.
  • Adding a semicolon turns it into a statement that returns nothing.

So this breaks:

fn add(a: i32, b: i32) -> i32 {
a + b; // ❌ the semicolon means "return nothing" — but we promised an i32
}

The compiler will complain that the function should return an i32 but doesn’t. Just remove the semicolon on the final line.

fn square(n: i32) -> i32 {
n * n
}
fn main() {
let result = square(5);
println!("5 squared is {result}");
}
▶ Try it Yourself
  • Define functions with fn, call them with name().
  • Parameters are inputs; each one needs a type: fn greet(name: &str).
  • Declare a return type with -> Type.
  • The last expression without a semicolon is the return value.
  • return value; works too, but is usually only used for early returns.

Quick check

1. In Rust, do you need to write the type of each function parameter?

2. How do you declare a function's return type?

3. What makes `a + b` (no semicolon) at the end of a function become its return value?

4. Does it matter whether you define a function above or below where it's called (e.g., above or below `main`)?

Score: 0 / 4