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: