Functions

Loading concept...

🏭 Rust Functions: Your Code Factory

Imagine you’re building a toy factory. Each machine in your factory does one specific job — one paints toys red, another adds wheels, another wraps them in boxes. In Rust, functions are like these machines. You feed them materials (inputs), they do their magic, and out comes something useful!


🎯 What Are Functions?

A function is a reusable block of code that does one job. Instead of writing the same code over and over, you write it once inside a function, give it a name, and call it whenever you need it.

Think of it like this:

  • Without functions: Every time you want a sandwich, you write down all 10 steps
  • With functions: You just say “make_sandwich()” and it happens!
fn say_hello() {
    println!("Hello, friend!");
}

fn main() {
    say_hello(); // Prints: Hello, friend!
    say_hello(); // Prints: Hello, friend!
}

The Anatomy of a Function

graph TD A["fn keyword"] --> B["function_name"] B --> C["#40; parameters #41;"] C --> D["{ body }"]

Key parts:

  • fn — Rust’s way of saying “here comes a function!”
  • name — use snake_case (lowercase with underscores)
  • parentheses — hold the inputs (can be empty)
  • curly braces — wrap the code that runs

📦 Function Parameters: Feeding the Machine

Parameters are the ingredients you give to your function. They’re like telling your sandwich machine what kind of bread and filling you want.

fn greet(name: &str) {
    println!("Hello, {}!", name);
}

fn main() {
    greet("Alice");  // Hello, Alice!
    greet("Bob");    // Hello, Bob!
}

Multiple Parameters

Your function can take many ingredients!

fn add_numbers(a: i32, b: i32) {
    println!("{} + {} = {}", a, b, a + b);
}

fn main() {
    add_numbers(5, 3);  // 5 + 3 = 8
}

Golden Rule: Every parameter needs a name AND a type. Rust wants to know exactly what it’s getting!

graph LR A["greet#40;name: &str#41;"] --> B["name = label"] A --> C["&str = type"]

🎁 Return Values: What the Machine Gives Back

Some functions don’t just do something — they give you something back. Like a vending machine: you put in money, you get a snack!

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

fn main() {
    let result = add(2, 3);
    println!("Result: {}", result); // Result: 5
}

How Return Works

  • Use -> followed by the return type
  • The last expression (without semicolon!) is returned
  • Or use return keyword explicitly
fn multiply(x: i32, y: i32) -> i32 {
    return x * y;  // explicit return
}

fn double(n: i32) -> i32 {
    n * 2  // implicit return (no semicolon!)
}

⚠️ Watch that semicolon!

fn broken() -> i32 {
    5;  // ERROR! Semicolon makes it a statement
}

fn works() -> i32 {
    5   // Perfect! This is an expression
}

⚡ Statements vs Expressions: The Secret Sauce

This is Rust’s superpower! Understanding this makes everything click.

Statements: Do Something, Return Nothing

A statement performs an action but doesn’t give back a value. It ends with a semicolon.

let x = 5;           // statement
println!("Hi");      // statement

You can’t do this:

let x = (let y = 6);  // ERROR! let is a statement

Expressions: Calculate and Give Back

An expression evaluates to a value. Most things in Rust are expressions!

5              // expression → 5
3 + 4          // expression → 7
{
    let x = 3;
    x + 1      // expression → 4
}

The Magic Block

Curly braces create a block expression:

fn main() {
    let y = {
        let x = 3;
        x + 1  // no semicolon = returns 4
    };
    println!("y = {}", y);  // y = 4
}
graph TD A["{block}"] --> B["let x = 3;"] B --> C["x + 1"] C --> D["Returns 4"]

Simple Rule:

Type Ends With Returns Value?
Statement ; ❌ No
Expression nothing ✅ Yes

🚀 Diverging Functions: The Never-Return Club

Some functions never come back. Like a one-way street with no U-turn!

These functions return the special type ! (called “never”).

Common Diverging Functions

fn forever() -> ! {
    loop {
        // runs forever!
    }
}

fn crash() -> ! {
    panic!("Something terrible happened!");
}

Why Use Them?

  1. Infinite loops (game loops, servers)
  2. Panic situations (unrecoverable errors)
  3. Exit the program completely
fn main() {
    let x: i32 = if true {
        5
    } else {
        panic!("Never reaches here!")
        // panic! returns !, which works
        // with any expected type!
    };
}

The ! type can become any other type, so it fits anywhere!


💬 Comments: Notes to Your Future Self

Comments are like sticky notes in your code. Rust ignores them, but humans love them!

Line Comments

// This is a single-line comment
fn main() {
    let x = 5; // comment at end of line
}

Block Comments

/* This is a
   multi-line
   block comment */
fn calculate() {
    /* quick note here */
}

Doc Comments (Super Special!)

/// Adds two numbers together.
///
/// # Examples
/// ```
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
fn add(a: i32, b: i32) -> i32 {
    a + b
}

Doc comments (///) generate documentation! They’re like instruction manuals for your functions.

graph TD A["// line comment"] --> D["Ignored by compiler"] B["/* block */"] --> D C["/// doc comment"] --> E["Generates docs!"]

🎮 Putting It All Together

Let’s build a tiny calculator using everything we learned!

/// Calculates the area of a rectangle.
fn area(width: i32, height: i32) -> i32 {
    width * height  // expression - returns!
}

/// Prints a friendly greeting.
fn greet(name: &str) {
    // This is a statement
    println!("Welcome, {}!", name);
}

fn main() {
    greet("Builder");

    let w = 5;
    let h = 3;
    let result = area(w, h);

    println!("Area: {}", result); // Area: 15
}

🌟 Quick Summary

Concept What It Is Example
Function Reusable code block fn say_hi() { }
Parameters Inputs with types fn add(a: i32, b: i32)
Return Value Output using -> -> i32 { a + b }
Statement Action, no value let x = 5;
Expression Evaluates to value x + 1
Diverging Never returns (!) fn crash() -> !
Comments Notes for humans // like this

🚀 You Did It!

You now understand how Rust functions work! Think of them as your code factory:

  1. Define the machine (function)
  2. Feed it inputs (parameters)
  3. Get outputs back (return values)
  4. Leave notes (comments)

Functions are the building blocks of every Rust program. Master them, and you can build anything! 🦀✨

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive - Premium Content

Please sign in to view this interactive content and start learning.

Upgrade to Premium to unlock full access to all interactive content.

Stay Tuned!

Interactive content is coming soon.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Cheatsheet - Premium Content

Please sign in to view this cheatsheet and start learning.

Upgrade to Premium to unlock full access to all cheatsheets.

Stay Tuned!

Cheatsheet is coming soon.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Quiz - Premium Content

Please sign in to view this quiz and test your knowledge.

Upgrade to Premium to unlock full access to all quizzes.

Stay Tuned!

Quiz is coming soon.

Flashcard Preview

Flashcard - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Flashcard - Premium Content

Please sign in to view flashcards and reinforce your learning.

Upgrade to Premium to unlock full access to all flashcards.

Stay Tuned!

Flashcards are coming soon.