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

Tags

rust