Traits

We can also define a collection of methods onto structures, then refer to the collection rather than an individual structure.

A trait, allows us to define a group of methods, and then implement them onto our structures.

// Create a trait called Valid
trait Valid {
    // ALL structures that wish to satisfy trait Valid must fill in these methods
    fn valid(&self) -> bool; // Note: We don't define it here!
}

// Let's define a Point structure
struct Point {
    pub X: u32,
    pub Y: u32
}

// Now to implement the Valid trait for Point structure
impl Valid for Point {
    // Now to fill in the method exactly as it's defined in the trait
    fn valid(&self) -> bool {
        // In this case, we simply check to ensure X and Y aren't zero
        self.X != 0 && self.Y != 0
    }
}

// Let's just define a simple main function
fn main() {
    // Creating a point
    let p: Point = Point{
        // Feel free to change X and Y in your own copy of this example
        X: 3,
        Y: 2,
    };
    // Calling the trait's method on Point
    if p.valid() {
        // I'll just print the individual fields from here
        println!("p ({}, {}) is valid", p.X, p.Y);
    } else {
        println!("p ({}, {}) is invalid", p.X, p.Y);
    }
}

Traits don’t have to have just 1 method, and in fact, a trait can refer to a custom value.

Some built-in traits that are good to define (or derive):

Some other traits that you might find/define: