Traits #1

This is an initial example of Traits in Rust. There are more complicated examples than this but to get started this is a nice way to understand how to create a Trait and how to use it.

Try the code:

Try this code in Rust Playground : https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6e50061eff5ac64ceed63bd55ff767e6

#[allow(dead_code)]

trait ShapeUtils {
    fn area(&self) -> f64;
}

struct Circle {
    cx: u8,
    cy: u8,
    r: f64,
}

impl ShapeUtils for Circle {
    fn area(&self) -> f64 {
        self.r * self.r * 3.14
    }
}

struct Rectangle {
    rl: f64,
    rw: f64,
}

impl ShapeUtils for Rectangle {
    fn area(&self) -> f64 {
        self.rl * self.rw
    }
}

fn main() {
    let myrectangle: Rectangle = Rectangle { rl: 10.1, rw: 5.0 };

    let mr = myrectangle.area();
    println!("Area of my rectangle {:?}", mr);

    let mycircle: Circle = Circle {
        cx: 8,
        cy: 8,
        r: 10.0,
    };

    let mc = mycircle.area();
    println!("Area of my circle {:?}", mc);
}

Note how the definition part on line 4 is the same as the definition inside each impl ?

The trait allows us to calculate the area irrespective of which shape we are trying to calculate the area of – we get the correct area returned regardless of what type of shape we use.

This example is partially based on an example in a Book called “Rust Crash Course” by Abhishek Kumar which I can really recommend.

Rust Crash Course – Abhishek Kumar

I first started to learn Rust with the Linkedin Course by Barron Stone, and have now added this book to give a fresh perspective on some of the topics.

This message will be printed for either struct type (Circle or Rectangle) when “print_shape” is called

Adding a default implementation of the Trait’s methods

If there is no custom implementation then this will run instead

trait ShapeUtils {
    fn area(&self) -> f64;
    // Add a default implementation to the Trait's methods
    fn print_shape(&self){
        println!("default implementation says : \"This is a geometric shape\"");
    }
}

struct Circle {
    cx: u8,
    cy: u8,
    r: f64,
}

impl ShapeUtils for Circle {
    fn area(&self) -> f64 {
        self.r * self.r * 3.14
    }
}

struct Rectangle {
    rl: f64,
    rw: f64,
}

impl ShapeUtils for Rectangle {
    fn area(&self) -> f64 {
        self.rl * self.rw
    }
}

fn main() {
    let myrectangle: Rectangle = Rectangle { rl: 10.1, rw: 5.0 };

    let mr = myrectangle.area();
    println!("{:?}", mr);

    let mycircle: Circle = Circle {
        cx: 8,
        cy: 8,
        r: 10.0,
    };

    let mc = mycircle.area();
    println!("{:?}", mc);
    
    // default message - because there is no custom implementation of print shape
    mycircle.print_shape();
    myrectangle.print_shape();

}