In this example, we will create a trait that will contain the signature for two functions: calc_perimeter and calc_area. To start with, we construct a struct. In this case, we will have two structs:
struct Perimeter
{
side_one: i32,
side_two: i32,
}
struct Oval
{
radius: f32,
height: f32,
}
We need to create a trait for each. The general format for a trait looks like this:
trait TraitName
{
fn function_name(&self) -> return_type;
}
In our case, we would have the following:
trait CalcPerimeter
{
fn calc_perimeter(&self) -> i32;
}
trait CalcArea
{
fn calc_area(&self) -> f32;
}
We now need to create an implementation for both of these traits. The impl, though, will not look quite the same.
Before, we had the following:
impl SomeImplement
{
...
}
This time, we have to give the name of the struct it relates to:
impl SomeImplement for MyStruct
{
...
}
If the impl defines the trait and the trait is just a stub, why do we need to say which struct it is for?
This is a fair question.
Without the trait, an impl operates in a similar way to a function. We supply the parameters to the impl via &self. When we have a trait, the impl has to say what &self refers to.
Our impl for the first trait will be as follows:
impl CalcPerimeter for Perimeter
{
fn calc_perimeter(&self) -> i32
{
self.side_one * 2 + self.side_two * 2
}
}
Note that the function can access side_one and side_two from the Perimeter struct.
The second impl will look like this:
impl CalcArea for Oval
{
fn calc_area(&self) -> f32
{
3.1415927f32 * self.radius * self.height
}
}
Finally, the calls to the implementations. Unlike previous examples, both of the structures have to be initialized and then the implementation call given:
fn main()
{
let peri = Perimeter
{
side_one: 5, side_two: 12 };
println!("Side 1 = 5, Side 2 = 12, Perimeter = {}",
peri.calc_perimeter());
let area = Oval
{
radius: 5.1f32,
height: 12.3f32
};
println!("Radius = 5.1, Height = 12.3, Area = {}",
area.calc_area()); }
Once the code has been compiled, the expected answer is as shown in the following screenshot: