Implementing methods
Methods are functions tied to a specific context, such as a struct, enum, or trait object. They can access the data of their parent type, utilize it for various operations, or modify it as needed. This allows for more organized and encapsulated code, making it easier to manage and maintain.
Defining methods
Methods are defined in the same way as functions, but with an additional first parameter self
. This self
parameter is either an owned value, an immutable reference, or a mutable reference to the parent type (in this case, a struct).
Let's stay we have a video game character named Dragon
with the following properties:
In a video game context, the dragon might have some properties like name
, level
, and fire_power
. Which we defined in the struct above as named fields.
A dragon can perform a few actions, like attacking, leveling up, moving and so on. These actions depend on the already existing data of the dragon, for example, we need to know the existing level of the dragon to know which level it should level up to.
Let's write a few methods, one will take an immutable reference, and one will take a mutable reference.
Method with immutable reference to self
If a method doesn't need to mutate any data on the struct, we'll use an immutable reference to self
. This is done by using &self
as the first parameter of the method.
The syntax of implementing method is similar to defining functions but inside a block of impl
with the name of the struct.
Method with mutable reference to self
Let's implement the level_up()
method to level up the dragon. This method will take a mutable reference to self
using &mut self
.
The level_up()
method takes a mutable reference to self
using &mut self
. This allows the method to modify the fields of the struct, in this case it's incrementing the level
and fire_power
of the dragon.
The &mut self
parameter is just a shorthand for dragon: &mut Dragon
, since this is a common pattern, Rust provides a shorthand syntax to make it easier to work with methods.
You can implement multiple methods inside the same impl
block, each method can have a different type of self
parameter. Let's define another method in the same impl
block.
Returning values from methods
You can also return values from methods. Just like functions, the return type of the function must be explicitly specified.
Let's add a return type of (u32, u32)
to the level_up()
method to return the new level and fire power of the dragon.
Using methods
Now that we have defined the methods, let's see them in action. We have a dragon named Mushu
which is at level
1
and has a fire_power
of 10
, he does a few attacks and then levels up.
When we run the code, we get the following output:
As you can see, we were able to call the methods on the mushu
instance of the Dragon
struct. The methods were able to access the fields of the struct and modify them as needed.
Associated functions
In addition to methods, Rust also has associated functions. These are functions that are defined on the struct itself and they do not take any reference to the struct as a parameter nor do they take ownership of the struct, they can be called without an instance of the struct.
Unlike methods, associated functions are called by using the ::
syntax on the struct itself, not on an instance of the struct. They are similar to static methods in other languages.
The most commonly used associated function in rust is the conventional new
function that is used to create a new instance of the struct, in other languages, this is usually a constructor, Rust doesn't have a constructor but instead you can define your own associated function to create a new instance of the struct.
You can define an associated function using the impl
block, just like you do with methods. The only difference is that you don't need to use &self
or &mut self
as the first parameter.
Let's add an associated function to the Dragon
struct that creates a new dragon with a given name:
The function above is not called a method but an associated function, it doesn't take any reference to any instance of the struct.
When we run the code, we get the following output:
Conclusion
In this lesson, we learned about methods and associated functions in Rust, how to define them and work with them.
Methods are functions that are tied to a specific context like a struct. They can access the data of their parent type, utilize it for various operations, or modify it as needed.
Associated functions on the other hand are functions that are defined on the struct itself and they do not take any reference to the struct as a parameter nor do they take ownership of the struct, they can be called without an instance of the struct and they're most commonly used to create a new instance of the struct, it's also a convention in Rust to name the constructor function new
.
In the next lesson, we have a challenge for you to help you practice what you've learned about defining methods and associated functions on structs in Rust.
Go to the next lesson when you're ready to take on the challenge. Good Luck!