Rust Functions
Functions are named blocks of code. Rust function names use snake_case, like total_price.
Defining and Calling Functions
Example
fn greet(name: &str) {
println!("Welcome to Workownix, {}!", name);
}
fn main() {
greet("Hamza");
greet("Sana");
}Welcome to Workownix, Hamza! Welcome to Workownix, Sana!
Every parameter must have a type. &str is a piece of text; you will learn more about it in the strings lesson.
Returning a Value
Write the return type after ->. The last expression in the function, without a semicolon, is the value returned.
Example
fn total(price: u32, qty: u32) -> u32 {
price * qty
}
fn is_even(n: i32) -> bool {
n % 2 == 0
}
fn main() {
println!("Bill: Rs {}", total(120, 5));
println!("{}", is_even(7));
}Bill: Rs 600 false
Statements and Expressions
This idea is important in Rust:
| Kind | Gives a value? | Example |
|---|---|---|
| Statement | No | let x = 5; |
| Expression | Yes | x + 1, if a > b { a } else { b } |
A semicolon turns an expression into a statement. So price * qty; with a semicolon would return nothing, and the compiler would show a "mismatched types" error.
If you get the error "expected u32, found ()", check whether you added a semicolon after the last line of the function. () is Rust's empty value.
Early Return
Use return to leave a function before the end:
Example
fn discount(bill: u32) -> u32 {
if bill < 1000 {
return 0;
}
bill / 10
}
fn main() {
println!("{}", discount(800));
println!("{}", discount(4500));
}0 450
Returning Several Values
Return a tuple to give back more than one value:
Example
fn min_max(numbers: &[i32]) -> (i32, i32) {
let mut low = numbers[0];
let mut high = numbers[0];
for &n in numbers {
if n < low { low = n; }
if n > high { high = n; }
}
(low, high)
}
fn main() {
let (low, high) = min_max(&[45, 12, 88, 30]);
println!("Lowest {}, highest {}", low, high);
}Lowest 12, highest 88
Closures
A closure is a small function without a name. Its parameters go between two vertical bars.
Example
fn main() {
let tax_rate = 0.17;
let with_tax = |price: f64| price + price * tax_rate;
println!("{}", with_tax(100.0));
let numbers = vec![1, 2, 3, 4, 5];
let squares: Vec<i32> = numbers.iter().map(|n| n * n).collect();
let evens: Vec<&i32> = numbers.iter().filter(|n| *n % 2 == 0).collect();
println!("{:?}", squares);
println!("{:?}", evens);
}117 [1, 4, 9, 16, 25] [2, 4]
The closure with_tax uses tax_rate from outside it. Closures can capture variables around them, normal functions cannot.
Exercise
Exercise
What does this function return? fn f() -> i32 { 10 + 5 }
