Rust Notes: Traits
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).
rust
// 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?
Generic Functions
Defining traits allows you to have generic functions that accept ANY type that satisfies the traits interface.
rust
// 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?
Trait Considerations
- In order to satisfy a traits interface, a type must implement all of the traits, associated functions and methods.
- The implementing types associated functions and methods signatures must match the traits signatures.
- Traits can be implemented by the following types:
- struct
- enum
- closure
- function
Links
https://www.manning.com/books/rust-in-action
https://www.udemy.com/course/ultimate-rust-crash-course/
https://doc.rust-lang.org/rust-by-example/trait.html