A trait represents a functionality. It defines a list of one or more methods that a type must implement in order to provide this functionality.
In Rust, almost any data type can implement a trait:
Structs.
Enums.
Primitive types.
Tuples.
Inside the standard library:
Many traits are defined (Clone, Copy, Debug, PartialEq, ...).
Most of them declare only one method.
Most of the provided types (structs, primitive types, ...) implement multiple traits.
A list of the most common traits of the standard library is available
in Table 1.
Among them are the comparison operators from the
cmp module.
Other operators (*, /, +, %, ...) are defined inside the
ops module. They
are listed inside the
ops traits
section.
Table 1:Some of the most common traits
Trait | Description |
|---|---|
To make a object clonable. | |
Reserved for copiable types. | |
To provide the Debug formatter. | |
To provide the Display formatter. | |
To set a default value for a type. | |
Like | |
Like | |
To provide operators | |
To provide operators |
20.1.1Defining a trait¶
As an example we want to create a trait Surface that defines a
method for computing the area. We will use this trait for a structure
Rectangle.
Here is the Rectangle structure:
struct Rectangle {
width: f64,
height: f64,
}And an instance of that structure:
let rect = Rectangle {width: 7.2, height: 9.5};To define a custom trait, we use the trait keyword. At least one
method must be defined, and only its declaration (i.e.: function’s
header, without a body) is necessary. In the following example, we
define the trait Surface with its method area():
trait Surface {
fn area(&self) -> f64;
}To implement the trait for our structure, we use the impl keyword in
its form impl <trait> for <struct>:
impl Surface for Rectangle {
fn area(&self) -> f64 {
self.width * self.height
}
}The area() method is now available for our rect object:
rect.area()68.4