Understanding Functions in Rust: A Comprehensive Guide

Learn Rust function syntax with small examples for typed parameters, return values, and tail expressions. Understand when a final expression returns a value.

Rust functions use fn, explicit parameter types, and an optional return type. This guide shows how to declare functions and return values through a final expression. The examples use the integer types covered in Rust scalar types.

Declaring Functions in Rust

Functions in Rust are declared using the fn keyword. The Rust style guide recommends using snake case for function names, which means all lowercase letters with underscores separating words. This naming convention promotes consistency and readability across your codebase.

fn my_function() {
    // function body
}
Rust

One of the conveniences Rust offers is the flexibility in the order of function declarations. Unlike some other languages, functions in Rust don’t need to be declared in any specific order. This allows you to structure your code in the way that makes the most sense for your project.

Function Parameters

When declaring a function in Rust, you can define parameters that the function will take. Parameters are declared with a name followed by a colon and the type.

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

If a function requires multiple parameters, you can separate them with commas:

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

Return Types in Functions

In Rust, -> introduces a function’s return type. A final expression without a semicolon can supply the return value. You can also use return to exit the function early.

fn square(num: i32) -> i32 {
    num * num
}
Rust

Shorthand Return: Tail Expressions

Rust provides a shorthand for returning values. If the last expression in a function’s block (known as the tail expression) does not end with a semicolon, its value is automatically returned. This feature can make your code more concise and readable.

fn multiply(a: i32, b: i32) -> i32 {
    a * b // No semicolon, so this value is returned
}
Rust

Example: Combining Everything

The following function takes two integers, squares both values, and returns their sum:

fn sum_of_squares(a: i32, b: i32) -> i32 {
    let square_a = a * a;
    let square_b = b * b;
    square_a + square_b // Tail expression, returned automatically
}
Rust

This function demonstrates the use of parameters, variable declarations within the function, and a tail expression for the return value.

Conclusion

Use typed parameters to make the function’s inputs explicit, and choose a return type that describes its result. A tail expression returns its value without return; a semicolon discards that expression’s value. Next, see if expressions and loops for conditional results, then references and borrowing for passing data without transferring ownership.

Share
Prabhat Kashyap

Prabhat Kashyap

Senior Technical Architect at HCLTech · working with Leonteq Security AG

I have 10+ years of experience building distributed systems and fintech platforms. I write about practical, non-obvious engineering details that official documentation often skips.

Newsletter

Get new engineering deep dives

Scala, JVM, AI, and backend systems. I send practical articles when there is something worth reading.

Join the newsletter