English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Rust Functions

Functions are ubiquitous in the Rust language.

Through the previous chapters, we have already learned the basic form of Rust functions:

fn <function_name> ( <parameter> ) <function_body>

In Rust, the naming style of function names is lowercase letters separated by underscores:

fn main() {
    println!("Hello, world!");
    another_function();
}
fn another_function() {
    println!("Hello, w3codebox!);
}

Running Result:

Hello, world!
Hello, w3codebox!

Note that we defined another_function after the main function in the source code. Rust does not care where you define the functions, just that they are defined somewhere.

Function parameters

In Rust, if a function needs to have parameters, it must declare the parameter name and type where the function is defined:

fn main() {
    another_function(5, 6;
}
fn another_function(x: i32, y: i32) {
    println!("The value of x is: {}", x);
    println!("The value of y is: {}", y);
}

Running Result:

The value of x is: 5
The value of y is: 6

Function body statements and expressions

The body of a Rust function consists of a series of statements that can end with an expression (Expression). So far, we have only seen functions that do not end with an expression, but we have already used expressions as part of statements.

A statement is a step that performs certain operations without returning a value. For example:

let a = 6;

This step does not return a value, so the following statement is incorrect:

let a = (let b = 2;

The expression has calculation steps and returns a value. Below is the expression (assuming that the identifiers that appear have been defined):

a == 7
b + 2
c * (a + b)

In Rust, you can write a more complex expression within a block enclosed by {}:

fn main() {
    let x = 5;
    let y = {
        let x = 3;
        x + 1
    };
    println!("The value of x is: {}", x);
    println!("The value of y is: {}", y);
}

Running Result:

The value of x is: 5
The value of y is: 4

It is obvious that this program contains an expression block:

{
    let x = 3;
    x + 1
};

Moreover, you can use function expressions in the block, and the last step is an expression, the result value of which is the entire expression block. This expression block is called a function body expression.

Note: x + 1 There is no semicolon at the end, otherwise it will become a statement!

This expression block is a valid function body. Moreover, in Rust, function definitions can be nested:

fn main() {
    fn five() -> i32 {
        5
    }
    println!("The value of five() is: {}", five());
}

Function Return Value

The way Rust function declaration returns a value type shown in the previous nested instance is: after the parameter declaration, use -> to declare the return type of the function (not : ).

You can end the execution of the function and return a value of an appropriate type at any time within the function body. This is the closest to the practice of most developers:

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

However, Rust does not support automatic return type inference! If the return type of the function is not explicitly declared, the function will be considered as "pure procedural", and it is not allowed to produce return values. The return value expression cannot follow return. The purpose of this is to allow public functions to form visible announcements.

Note:The function body expression is not equivalent to the function body, it cannot use return Keywords.