Rust Functions
A function is a named block of code that a program can run again and again. Values go in as parameters.
The same lines, written twice
Two greetings repeat the same welcome line. A change means editing every copy:
fn main() {
println!("Hello, Ana!");
println!("Welcome back.");
println!("Hello, Bo!");
println!("Welcome back.");
}Write a function, then call it
fn declares a function. main has carried every program so far — your own functions work the same way:
fn say_hello() {
println!("Hello from a function!");
}
say_hello();Give it values: parameters
The names in the definition are parameters, and every parameter must name its type. The values you pass when calling are the arguments:
fn show(score: i32) {
println!("score = {}", score);
}
show(90);The last expression is the answer
The type after -> is the type the function gives back. The last expression in the body, with no semicolon, is that value:
fn double(n: i32) -> i32 {
n * 2
}
println!("double = {}", double(21));Leave early with return
Use the word return only when you want to leave before the end:
fn classify(n: i32) -> i32 {
if n < 0 {
return -1;
}
n
}
println!("{}", classify(-5));
println!("{}", classify(7));No return type means ()
Leave the -> part out and the function gives back the unit value (). Writing -> () instead means exactly the same thing:
fn announce(score: i32) {
println!("score = {}", score);
}
let got = announce(90);
println!("announce gave {:?}", got);Example
fn celsius(f: f64) -> f64 {
(f - 32.0) * 5.0 / 9.0
}
fn main() {
println!("98.6F = {:.1}C", celsius(98.6));
}Key points
- Functions can be written in any order — Rust finds them all
- Some functions never give back at all.
- One example stops the program.
- Their return type is the special !
- Rust has no overloading: one name means one function.
- You cannot write two functions with the same name.
- Different inputs do not help.
- Use two names instead.
- Or use one function.
- That function can take a tuple.
- It can take an enum
- A function always takes a fixed number of inputs.
- Parameters have no default values.
- Every call passes every value.
- It passes them every time.
- Macros such as println! are the escape hatch when a call needs a variable number of arguments
- Every argument travels into the function in one of two ways.
- It can travel by value.
- Then the function receives the value itself.
- It can travel by reference.
- Then it borrows yours.
- A function is one named block: every call runs the same block again.
In this example, celsius takes a decimal number f and gives back a decimal. The body is one expression: (f - 32.0) * 5.0 / 9.0. There is no semicolon, so this value is the answer. In main, celsius(98.6) is called, and {:.1} prints the result with one decimal digit: 37.0. Say you added a semicolon to that line. Then the function would give back nothing instead. The code would stop compiling.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
What happens if you add a semicolon to the last expression of a function?