iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Functions

Rust functions are typed end-to-end. Parameters declare types; the return type follows ->. The last expression (no semicolon) is the return value — idiomatic Rust uses this heavily.

Signatures + expressions + early return

EXAMPLE
// Basic
fn add(a: i32, b: i32) -> i32 {
    a + b   // no semicolon — this expression is the return value
}

// Early return
fn safe_div(a: f64, b: f64) -> Option<f64> {
    if b == 0.0 {
        return None;
    }
    Some(a / b)
}

// Multiple returns via tuple
fn divmod(a: i32, b: i32) -> (i32, i32) {
    (a / b, a % b)
}
let (q, r) = divmod(17, 5);

// Generic + trait bound
fn largest<T: PartialOrd + Copy>(xs: &[T]) -> T {
    let mut best = xs[0];
    for &x in xs.iter().skip(1) {
        if x > best { best = x; }
    }
    best
}

// Closures — anonymous functions, capture environment
let add5 = |x| x + 5;
let vec  = vec![1, 2, 3];
let sum: i32 = vec.iter().map(|&x| x * 2).sum();

// Function pointers / higher-order
fn apply(f: fn(i32) -> i32, x: i32) -> i32 { f(x) }
println!("{}", apply(|n| n + 1, 9));   // closures that don't capture coerce to fn

Why it matters

Functions are expressions all the way down. Avoid return at the bottom — let the last expression be the value. It’s shorter and matches the way Rust is written everywhere.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
fn add(a: i32, b: i32) -> i32 {
    a + b   // no semicolon = return
}

fn main() { println!("{}", add(2, 3)); }
Try it Yourself »

Exercise

Return-type arrow syntax.

fn add(a: i32, b: i32) i32 { a + b }

Discussion

Loading…