Functions

https://doc.rust-lang.org/reference/items/functions.html

The fn keyword declares a function:

#![allow(unused)]
fn main() {
fn hello_world() {
    println!("Hello, world!");
}
}

This function returns nothing, it is void. In Rust, you'd write the 'void' type as () and call it unit.

Here's a function that returns an unsigned integer. Use the arrow type to indicate:

#![allow(unused)]
fn main() {
fn my_favorite_number() -> u64 {
    20090301 // launch of bitcoin ;-)
}
}

Brackets denote code blocks:

fn main() {
    let outside = "first";
    {
        let inside = "second";
        println!("{}", inside);
    }
    println!("{}", outside);
}
// result: second, first

Blocks are also expressions, which mean they evaluate to a value. TIP: You will find that all control structures in Rust are actually expressions - use wisely.

The return value of a function, block or a control structure is the last statement without a semicolon. However, the return can be used to end a function early:

#![allow(unused)]
fn main() {
fn unreachable_code() -> i32 {
    return 0;
    println!("this will never happen");
}
}

Functions can be generic:

#![allow(unused)]
fn main() {
fn fun<T>(_parameter: T) {
    // do something
}
}

They can have multiple type parameters, which can then be used in the function's declaration and its body, instead of concrete types:

#![allow(unused)]
fn main() {
fn foobar<L, R>(left: L, right: R) {
    // do something with `left` and `right`
}
}

Type parameters usually have constraints, so you can actually do something with them.

The simplest constraints are just trait names:

#![allow(unused)]
fn main() {
fn print<T: Display>(value: T) {
    println!("value = {}", value);
}
}

There's a longer syntax for type parameter constraints:

#![allow(unused)]
fn main() {
fn print<T>(value: T)
where
    T: Display,
{
    println!("value = {}", value);
}
}

Constraints can be more complicated: they can require a type parameter to implement multiple traits:

#![allow(unused)]
fn main() {
fn print<T>(value: T)
where
    T: Display + Clone,
{
    println!("value = {}", value.clone());
    // Rust is actually fairly big-brained, so clippy
    // would tell you this clone is not necessary
}
}