Functions
Rust is a systems programming language focused on speed, memory safety, and fearless concurrency — and functions are how you package logic into reusable, named building blocks.
Learn Functions in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll define functions with fn , pass typed parameters, return values, and understand Rust's distinction between statements and expressions.
What You'll Learn in This Lesson
1️⃣ Defining and Calling Functions
You define a function with the fn keyword, a name, a parenthesised list of typed parameters, and an optional for the return value. Every parameter must have a type annotation. To return a value, make the last line an expression with no semicolon .
Notice add ends with a + b and no semicolon — that expression is the return value. The function greet has no , so it returns nothing and exists only to print.
2️⃣ Statements, Expressions, and Early Returns
This is the idea that trips up newcomers: in Rust a block {' '} is itself an expression that evaluates to its last value. That means if blocks and even nested blocks can produce values. The return keyword still exists for leaving a function early.
The block assigned to y evaluated to 9 because inner * inner had no semicolon. In describe , the early return handles the even case, and the final if expression provides the rest.
Your turn. Fill in the blanks marked ___ , then run it.
Write two functions yourself and call them from main . Run it with cargo run and check the output.
📋 Quick Reference — Functions
Practice quiz
Which keyword defines a function in Rust?
- func
- def
- fn
- function
Answer: fn. Functions are defined with the fn keyword, e.g. fn add(a: i32, b: i32) -> i32.
What declares a function's return type?
- An arrow -> after the parentheses
- A colon before the body
- The returns keyword
- A => symbol
Answer: An arrow -> after the parentheses. The -> after the parameter list declares the return type, e.g. fn f() -> i32.
What becomes a function's return value?
- The first line
- Any line with return only
- The function name
- The last expression with no semicolon
Answer: The last expression with no semicolon. The last expression in the body, with no trailing semicolon, is the return value.
What happens if you add a semicolon after the final expression a + b?
- Nothing changes
- It becomes a statement evaluating to (), often causing a type mismatch
- It returns twice
- It panics
Answer: It becomes a statement evaluating to (), often causing a type mismatch. A trailing semicolon turns the expression into a statement returning (), so a fn meant to return i32 won't compile.
Must every function parameter have an explicit type?
- Yes, every parameter must be annotated
- No, types are inferred
- Only the first one
- Only for return values
Answer: Yes, every parameter must be annotated. Unlike local variables, function parameters always require explicit type annotations.
What does a function with no -> in its signature return?
- i32
- null
- The unit type ()
- An error
Answer: The unit type (). Without ->, a function returns the unit type (), meaning no meaningful value.
In Rust, a block { } is...
- only a grouping of statements
- an expression that evaluates to its last value
- always empty
- the same as a loop
Answer: an expression that evaluates to its last value. A block is an expression; its value is the last expression inside it (with no semicolon).
What is the value of let y = { let inner = 3; inner * inner };?
- 3
- 6
- ()
- 9
Answer: 9. The block evaluates to inner * inner = 9 because that line has no semicolon.
When should you use the return keyword?
- Always, at the end
- For an early exit from the middle of a function
- Never
- Only in main
Answer: For an early exit from the middle of a function. Use return to exit early; the idiomatic happy-path result is a final expression with no semicolon.
Does Rust support default argument values for functions?
- Yes
- Only for the last parameter
- No — you must pass every parameter the signature lists
- Only with a macro
Answer: No — you must pass every parameter the signature lists. Rust has no default arguments; every parameter in the signature must be provided at the call site.