updated: 27th of February 2022
published: 19th of February 2022
A trait in Rust is similar to an interface in other languages. Traits define the required behaviour a type MUST implement to satisfy the trait (interface) .
// Define a `Greeter` trait.
trait Greeter {
// To satisfy the `Greeter` trait, types must
// implement a `hello` method that returns a `String` type.
fn hello(&self) -> String; // `&self` is the caller type.
}
// Structs that implement the `Greeter` trait.
struct Person {
name: String,
greeting: String,
}
struct Dog {}
// Implement the `Greeter` trait for the `Person` struct.
impl Greeter for Person {
// Method signature matches `Greeter::hello`
fn hello(&self) -> String {
// Unique implementation details
format!("{}! my name is {} :)", self.greeting, self.name)
}
}
// Implement the `Greeter` trait for the `Dog` struct.
impl Greeter for Dog {
// Method signature matches `Greeter::hello`
fn hello(&self) -> String {
// Unique implementation details
"Bark! Bark! Bark! Woof?".to_string()
}
}
// Create concrete instances of the `Person` and `Dog` types.
let bobby_diggle = Person{
name: String::from("Bobby Diggle"),
greeting: String::from("你好"),
};
let brian = Dog{};
// Call the `hello` method on each type.
println!("{}", bobby_diggle.hello()); // => 你好! my name is Bobby Diggle :)
println!("{}", brian.hello()); // => Bark! Bark! Bark! Woof?
Defining traits allows you to have generic functions that accept ANY type that satisfies the traits interface .
// Generic function `say_hello` that accepts any concrete type `(T)`
// that implements the `Greeter` trait.
fn say_hello<T: Greeter>(item: T) { // `item` is the passed in type.
println!("{}", item.hello());
}
say_hello(bobby_diggle); // => 你好! my name is Bobby Diggle :)
say_hello(brian); // => Bark! Bark! Bark! Woof?
https://www.manning.com/books/rust-in-action