Classes in Rust?
Considering how popular OOP, you might have wondered whether there are classes in Rust. The first language that I learned was Rust language. Before learning Rust I had a little bit of an idea of programming languages and the fundamentals. In high school, we learned the basic concepts of programming using C language. Before that, in my 10th grade, we learned programming using GWBASIC (Hey, it helped Ok).
However, I knew the concepts but still I was not very good. During my summer breaks, I took admission in the PIAIC IoT (Internet of Things) program. In the first quarter, we learned the Rust language. I was really sure that I would grasp all the concepts really easily.
Well, the start was easy, I was flying through the fundamentals. Then came the part on which I pulled my hair. The ownership, strings, traits, etc. But, I managed to pull through. After Rust language, I started learning Python. Let me tell you, that was the point when I found out the meaning of life. Just kidding, but Python helped me in deepening my knowledge so much more. I learned a lot. The way I looked at Rust, changed. Everything finally made sense. At this time I realized that oop in Rust exists.
If you want a short, simple answer: There are no classes in Rust, but there are ways we can perform OOP in Rust, through Rust structs.
Introduction to Structs in Rust Language
There are no classes in Rust but structs.
The definition of Rust struct in The Book is:
A struct, or structure, is a custom data type that lets you name and package together multiple related values that make up a meaningful group.
Sounds really familiar right? C language also contains structures that are similar to the Rust structs.
But if we dig deep down in Rust struct, we will discover that they are way different then C structures. C structures are a group of variables with different data types represented by a single name, and that is pretty much it. There is nothing much that you can do. You can define functions that can take this structure and process it, but it is very generic and does not provide context. This where Rust struct differs.
Rust structs are really similar to Java classes. The syntax differs but the main functionality of Rust structs is the same as Java classes. You will see in the code that we will write below, how structs in Rust can offer methods, interfaces etc.
In Rust struct, you define data just like in C language. You use a keyword struct and then you give the name. Inside the curly braces, you enter the names and types of the pieces of data, which are known as fields.
Here we have defined a Rust struct called User that stores the name and age of the user. To use the struct after you have defined it, you create an instance of that struct. Classes have instances, similarly, Rust structs have instances too as shown in the code below.
Here we have created the instance of User. The variable that holds the values now has a data type of User and values in the name and age field are “John Doe” and 32 respectively. You will notice that you do not need a constructor function to create an instance of the object. Although if you want to create a constructor, you can certainly do that, it is not necessary.
Until now, everything that we have done is similar to C. Here comes the OOP in Rust part. I said earlier that there are no contextualized functions in C structures. In Rust struct though, we have functions known as methods which are defined the context of the structs. These methods are exactly the same as Java methods. Here is how you define a method for a Rust struct that we defined earlier.
To define a function in the context of the Rust struct, you start an implementation block by using the keyword impl. Then you define the functions. The function name defined here is returning the name value of the User instance that was passed in. To call the method on our instance. In the main function, write the line that is mentioned below:
The &self in the function signature will take the instance of the rust struct, user1 is the instance in our example
Alright, so the people coming from OOP background will start to realize the similarities. After looking at the code examples above, we can get a vague idea of how the developers implement oop in Rust. We can see how a Rust struct can act as a class and how oop in Rust can be achieved. Let us properly look at the similarities.
Similarities In Classes and Structs
The first thing which clicks in mind after looking at Rust struct’s fields is the class’s attributes in oop. When you define a class you provide some attributes in which the instance data will be stored later. This is one of the reasons why structs can be thought of as classes in Rust. Both classes and Rust struct need attributes to work upon. The value of the attributes can be modified and can be used in the program easily. You can think of the ways in which you can use Rust struct as classes in Rust. Unlike Java, if the structs are defined in the same module, you do not explicitly have to make the fields public.
After looking at the instance definition, you can understand why structs can act as classes in Rust
Another similarity between classes and structs in Rust is the methods. The contextualized functions. In OOP languages, methods are used extensively to work with the attributes of the object. The getter and setter methods are used to read and update values. Similarly, methods in Rust struct can be defined in any way. You can see, how structs in Rust language can act as classes in Rust.
They can be used in exactly the same way as OOP. Methods in Rust can be used to update values, read values. It depends on the programmers in what way they are going to implement the methods.
The function definition is also very similar. Methods defined Rust structs always take &self as the first argument. If you have a background of any OOP language, you can easily identify this similarity.
Another similarity to prove classes in rust is the concept of Trait. A Trait is a feature by which we can tell the Rust language compiler about the functionality a particular type has and can share it with other types. In Java, an interface does the same thing. If we can call similar methods on different types we can say that the types have the same behaviour. We achieve this functionality in Rust via traits.
In Rust language, traits are used to define shared behaviour and to create inheritance. It depends on the developer on how they want to use it.
We will see an example in which we will define a trait and will see how a function can be made to accept two different types as parameters.
First, we will define two structs.
Here we have defined two structs that are of two different data types. Now we will define a trait called Information. In that trait, we will have a method called show. When the trait is implemented on Student, the show method will return the class field’s value, and when the trait is implemented on the Teacher, the method will return the subject that the teacher teaches.
We just created an interface! It is very similar to the concept of the interface in other OOP languages. This is another reason why structs can act as classes in Rust. After you get the hang of structs and traits in Rust, you will be able to see the similarities in classes and structs.
Why Not Just Add Classes In Rust?
After reading all of this. You might be thinking that why the developers did not just add class keywords like C++ and Java. If they were keen on adding oop in Rust, they could have made a better syntax which would be understandable when you look at it the first time. So why cannot just add classes in Rust and make life easy for everyone?
The developers of Rust language do not provide any clear answers related to this question. The answers that do exist are really different from one another. Everyone has a different opinion.
Before proceeding further, you should know that I am still a student. So the opinions that I will share should be taken as a grain of salt.
Rust language is hugely inspired by the C language. Rust is capable of doing low-level systems programming. You can say that it was just a design choice. Someone who is interested in low-level systems programming in Rust, they can easily grasp the concept due to C language. For the people coming from the OOP background, they can also merge their previous knowledge in understanding concepts of oop in Rust. This might be a reason why they did not add classes in Rust.
Rust is a general-purpose programming language. It was designed in a way such that people from any programming background can use it comfortably. Directly adding classes in Rust could have been a reason to call Rust language as Object Oriented. You should know that other than oop in Rust there are some features that relate to functional programming too.
Adding specific features could have titled Rust as a language for a specific paradigm. This is why in Rust the similarities between classes and structs would have to be created using a different way. In a more general-purpose way.
After reading this article, I hope you understand how classes and structs are similar. Although I did not dig deeper or this article would have been very long. You can look at this article to know more about oop in Rust.
If you want to read more take a look at these articles.