Skip to content

Functions, Statements and Comments

This page covers Rust functions, statements, expressions and comments.

Functions

Functions are prevalent in Rust code. You’ve already seen one of the most important functions in the language: the main function, which is the entry point of many programs. You’ve also seen the fn keyword, which allows you to declare new functions.

We define a function in Rust using fn keyword followed by a function name and a set of parentheses. You can also call any function inside another function:

rust
fn main() {
    println!("Hello, world!");

    another_function();
}

fn another_function() {
    println!("Another function.");
}

Notice that another_function is defined after main function. Rust doesn’t care where you define your functions, only that they’re defined somewhere in a scope that can be seen by the caller.

Parameters

A function can have parameters, which are special variables that are part of a function’s signature. When you call the function, you give it arguments, which are the actual values for those parameters. Technically, parameters are the variables in the function definition and arguments are the values you pass in, but people often use the two terms interchangeably.

rust
fn main() {
    another_function(5);
}

fn another_function(x: i32) {
    println!("The value of x is: {x}");
}

In function signatures, you must declare the type of each parameter. This is a deliberate decision in Rust’s design: requiring type annotations in function definitions means the compiler almost never needs you to use them elsewhere in the code to figure out what type you mean. The compiler is also able to give more helpful error messages if it knows what types the function expects.

Statements and Expressions

In Rust, a function’s body is made up of statements and sometimes ends with an expression. Understanding the difference between the two is important because Rust is an expression-based language.

  • Statements are instructions that perform some action and do not return a value.
  • Expressions evaluate to a resultant value.

For example:

rust
fn main() {
    let y = 6;
}

Here, let y = 6; is a statement. It creates a variable but doesn’t return anything. Because statements don’t return values, you can’t do something like this:

rust
let x = (let y = 6); // This gives an error

Other languages, such as C and Ruby, where the assignment returns the value of the assignment, allow something like this: x = y = 6;, but that is not the case in Rust.

Most of your Rust code will be expressions. For example:

NOTE

In Rust, numbers by themselves are also expressions.

  • 5 + 6 is an expression that evaluates to 11.
  • Calling a function or macro is an expression.
  • A block surrounded by {} can also be an expression.

Example:

rust
fn main() {
    let y = {
        let x = 3;
        x + 1
    };

    println!("The value of y is: {y}");
}

Note that the x + 1 line doesn’t have a semicolon at the end. This is because the expressions in Rust don't end with semicolons.

IMPORTANT

Expressions don’t end with semicolons. If you add a semicolon, it becomes a statement and stops returning a value.

Functions with Return Values

Functions can return values to the code that calls them. We don’t name return values, but we must declare their type after an arrow (->).

In Rust, the return value of the function is synonymous with the value of the final expression in the block of the body of a function. You can, however, return early from a function by using the return keyword and specifying a value, but most functions return the last expression implicitly. Here’s an example:

rust
fn five() -> i32 {
    5
}

fn main() {
    let x = five();

    println!("The value of x is: {x}");
}

Function without a return type doesn't return a value, or more precisely, it returns the special unit type ().

Comments

Comments in source code are ignore by compiler. They are needed to explain your code so others (or your future self) can understand it better.

In Rust, comments start with // and go to the end of the line. If you need multiple lines, just start each one with //:

rust
// This part of the code does something tricky,
// so we're adding extra explanation here.

You can also put comments at the end of a line of code:

rust
let lucky_number = 7; // I'm feeling lucky today

However, it’s more common to put comments above the code they describe:

rust
// I'm feeling lucky today
let lucky_number = 7;

Block Comments

In addition to the standard // style, Rust also supports block comments, written with /* ... */.

rust
/*
This is a multi-line comment.
It can span as many lines as you want.
*/
fn main() {
    println!("Hello, world!");
}

You can even nest block comments - something many languages don't allow:

rust
/* 
This is a block comment.
    /* And this is a nested comment inside it! */
Back to the outer comment.
*/

Rust also has another kind of comment, documentation comments, which are covered later.