Rust Lang

Rust Functions

This guide will explore how to create and use functions in the Rust programming language. Functions are a universal feature in most programming languages and fundamental for any developer to know.

What is a Function?

Before getting into the details of creating and using a function, let us break down what a function is and why to use it.

A function is nothing more than one or more block of code that is grouped together and performs a single entity. Functions are a heavy feature in most programming languages as they allow us to organize and export code to other parts of the program in a readable pattern.

By now, you have come across the main function in the Rust language. The main function is a special type of function that serves as the entry point for a rust program.

With that out of the way, let us discuss how to create and use functions in Rust.

Rust Functions

The following are the steps to take when defining a function in Rust.

  1. We start with the keyword fn.
  2. Next, we set the name of the function.
  3. A pair of parentheses and passes a list of parameters.
  4. Define a function body using opening and closing curly braces.
  5. Finally, a return value (if available).

We can express the above code in the syntax shown below:

fnfunction_name(parameters){
    // function body
}

The most basic type of function is one that does not accept any parameters nor contains a return value. We can define such a function as shown in the example below:

fn say_hello() {

println!("Hello world");

}

The above illustrates the most basic concept of a function definition. We start with the keyword fn followed by the name of the function, in our case, say_hello(). We then open the function body inside a pair of curly braces.

The function body contains nothing but the logic of what the function does. Occasionally, a function will call other functions and use them.

Calling a Function

Once we have a function declared, we can use it to perform the defined actions. We refer to the process of using a function as a function call or invoking a function.

In rust, we call a function by providing its name and a pair of parentheses. This tells the compiler that we wish to execute the instructions defined in that function.

In our example, we can call our function inside the main function as shown in the example below:

fn main() {

//! Call the function

say_hello();

}

/// function declaration

fn say_hello() {

println!("Hello world");

}

Function Parameters

One of the principal reasons for using functions is to pass parameters. A parameter is a special type of variable that we can pass to the function and allow modification of the logic that the function uses.

You may often hear the terms word parameter and argument used interchangeably. Although they have a difference, it’s really nothing to stop you from building tools with Rust.

To define a set of function parameters, we start by defining the parameter name followed by its type inside the function parentheses.

The syntax is as shown:

fn function_name(parameter1: data_type) {

   // function body

}

Note you must perform type annotation for a function parameter.

Let us take the say_hello function we defined earlier and improve it so that it says hello to the specific user.

We can do:

fn say_hello(name:&str) {

println!("Hello, {}", name);

}

In the example above, we define a parameter for the say_hello function of type &str. We can now pass a name to the function, and it will greet us with the provided name.

To pass the parameter during the function call, we can do:

fn main() {

say_hello("Sarah!");

}

fn say_hello(name:&str) {

println!("Hello, {}", name);

}

Function Statement and Expression

As mentioned, a function body comprises code statements that perform an action. We have used a defined macro to print something to the screen in our example. However, we can create custom logic for our functions.

For example, take the function below that takes two integers and return the maximum of the two:

fnmaximum(x: i32, y: i32) {
    let mut max = 0;
    if x>y {
max = x;
    } else {
max = y;
    }
println!("Max value is: {}", max);
}

We can then call the function and pass the two integer values as shown below:

fn main() {

maximum(100, 50);

}

Running the code above should print:

Max value is: 100

Function Return Values

A function can also return a value based on the logic and actions it performs. We can then use the value returned from the function to perform other operations. Although we do not name the return value in a function, we need to tell the compiler that we expect the function to return a value of a specific type.

We do this using the arrow -> notation.

Take the maximum() function we defined earlier. Instead of printing the max value, we can have the function return the max value, and we can use it to act on other parts of the program.

To define a function return type, we can use the syntax as:

fn function_name(parameter: type) -> return_type {

  // function body

}

Consider the example below that re-defines the maximum function to include a return value:

fn maximum(x: i32, y: i32) -> i32 {

  // logic

}

In this case, we expect the function to return an i32 type.

Once we have defined a function return type, we need to make sure the function actually returns something.

We can do this using the return keyword. For example, to return the maximum value from the function above, we can do:

fnmaximum(x: i32, y: i32) -> i32 {
    let mut max = 0;
    if x>y {
max = x;
    } else {
max = y;
    }
    return max;
}

The function should return the value of the max variable.

Another format we can use to return a value from a function is to specify the return value with no semi-colon terminator.

An example is as shown:

fnmain() {
say_hello("Sarah!");
    maximum(100, 50);
}
fnsay_hello(name:&str) {
println!("Hello, {}", name);
}
fnmaximum(x: i32, y: i32) ->i32 {
letmut max = 0;
if x > y {
        max = x;
    } else {
        max = y;
    }
// no return keyword or semi-colon
    max
}

The above example should behave similarly to the return keyword.

We can then use the value returned from the function to perform an action. For example:

fn main() {

println!("Product: {}", maximum(100, 10) * 2);

}

Here, we take the value returned from the maximum function and multiply it by 2.

In Closing

For this tutorial, we explored the concept of functions, how to define a function, function parameters, function return values, and more. Functions are an important concept in programming, and they allow us to organize and re-use code without repetition.

We hope you enjoyed the tutorial.

Bye for now!

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list