A function in Rust starts with fn
. For example:
fn main() {
// Body
}
main()
is the most important function and is where the Rust program starts.
Rust does not care where a function is defined, it just needs to be defined. For example:
fn main() {
other_function();
}
fn other_function() {
println!("This function is declared after main. It could have been declared before main.");
}
You can pass functions as parameters to functions as well! The fn
type is a function pointer.
Function pointers implement all three closure traits Fn
, FnMut
, and FnOnce
).
fn double(x: u32) -> u32 {
x * 2
}
fn do_twice(f: fn(u32) -> u32, arg: u32) -> u32 {
f(arg) * f(arg)
}
fn main() {
assert_eq!(
16,
do_twice(double, 2)
)
}
Type annotations for parameters are required in Rust.
fn main() {
other_function(12, 'a');
}
fn other_function(x: i32, c: char) {
println!("The value of x is: {}", x);
println!("The value of c is: {}", c);
}
Rust requires you to declare a return type for a function if it returns something.
The last line in a function is returned implicitly as long as it is an expression (no semi-colon). A return
statement can be used to return prior to the last line.
fn three() -> i32 {
3 // Notice the lack of a semi-colon. Expressions return something, statements do not.
}
fn plus_one(x: i32) -> i32 {
x + 1
}
fn minus_one(x: i32) -> i32 {
// Because we are explicitly using "return" we can either make this
// a statement or an expression.
return x - 1;
}
fn no_return(x: i32) {
println!("{}, x");
}
fn main() {
let x = three();
println!("x is: {}", x);
let x = plus_one(x);
println!("x is now: {}", x);
let x = minus_one(x);
println!("x is finally: {}", x);
}