Rust Functions Explained: Parameters, Return Values and Error E0308
November 10, 2026
Welcome to episode 4 of Rust for Beginners, a series for complete beginners (no programming experience needed). In the last video, we learned about variables and data types. Today, we'll learn how to write functions in Rust. Every code block below is the exact code from the video, ready to copy.
- All episodes are in the Rust Tutorial for Beginners playlist.
- Versions used: Rust 1.99.1 on Ubuntu, VS Code with rust-analyzer.
1. New project
Let's create a new project called functions, and open it in VS Code.
cargo new functions
cd functions2. main
Every Rust program starts in the main function. We write the fn keyword, the name, parentheses, and the body in curly braces.
3. Define
Let's write our own function, called say hello. Function names in Rust use snake case: lowercase words joined by underscores.
src/main.rs:
fn main() {
say_hello();
say_hello();
}
fn say_hello() {
println!("Hello from a function!");
}Output: Hello from a function! (twice)
4. Call
We call it from main with its name and parentheses. The order doesn't matter: a function can be defined after main.
5. Run A
Let's run it. The message prints twice, once for each call.
cargo run6. Parameters
Functions can take parameters. Here, the print sum function takes two numbers, a and b. Every parameter needs a type.
fn main() {
print_sum(5, 7);
print_sum(10, 20);
}
fn print_sum(a: i32, b: i32) {
println!("{a} + {b} = {}", a + b);
}Output: 5 + 7 = 12 / 10 + 20 = 30
7. Arguments
When we call it, we pass in values, called arguments: five and seven, then ten and twenty.
8. Run B
Let's run it.
cargo run9. Return type
Functions can also return a value. We write the return type after an arrow. Here, add returns an i thirty-two.
fn main() {
let result = add(5, 7);
println!("5 + 7 = {result}");
println!("Double: {}", double(result));
}
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn double(x: i32) -> i32 {
x * 2
}Output: 5 + 7 = 12 / Double: 24
Then line 8 becomes a + b;. Error:
error[E0308]: mismatched types
--> src/main.rs:7:27
|
7 | fn add(a: i32, b: i32) -> i32 {
| --- ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
8 | a + b;
| - help: remove this semicolon to return this value10. Last expression
Notice there's no semicolon after a plus b. The last expression in a function is its return value.
11. Use it
In main, we store the result in a variable, and print it. We can also pass it straight into another function, double.
12. Run C
Let's run it.
cargo run13. Semicolon
What happens if we add a semicolon after a plus b?
cargo run14. Error
With a semicolon, it becomes a statement, and a statement returns nothing. But we promised an i thirty-two, so Rust refuses. The compiler even tells us to remove the semicolon.
15. Fix
Let's remove it, and run again. Now it works.
cargo runRecap
To recap: fn defines a function, parameters need types, the arrow sets the return type, and the last expression, without a semicolon, is the return value.