Implementing Traits
Part of the Object Oriented Programming section of Coddy's Rust journey — lesson 30 of 61.
Now that you know how to define a trait, let's see how to make a struct fulfill that contract. Implementing a trait connects the abstract requirement to concrete behavior.
The syntax uses impl TraitName for StructName:
trait Speak {
fn speak(&self) -> String;
}
struct Dog {
name: String,
}
impl Speak for Dog {
fn speak(&self) -> String {
format!("{} says: Woof!", self.name)
}
}
The impl Speak for Dog block tells Rust that Dog is implementing the Speak trait. Inside, you provide the actual method body—this is where you define how a dog speaks.
The power of traits becomes clear when multiple types implement the same one:
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
Both Dog and Cat now share the Speak capability, but each provides its own unique implementation. You can call .speak() on either type:
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex says: Woof!
println!("{}", cat.speak()); // Whiskers says: Meow!
This is the foundation of polymorphism in Rust—different types, same interface, unique behaviors.
Challenge
EasyLet's bring traits to life by implementing them for different types! You'll create a Describable trait and implement it for two different structs, each providing its own unique description.
You'll organize your code across three files:
describable.rs: Define a publicDescribabletrait with a methoddescribe(&self) -> String.items.rs: Create two public structs that implement your trait:Bookwith a publictitlefield (String)Moviewith a publicnamefield (String)
Describablewith its own unique description format.main.rs: Bring your modules together, create instances of both structs, and call theirdescribemethods to show how the same trait produces different outputs for different types.
Your Book should describe itself as Book: {title} and your Movie should describe itself as Film: {name}. Notice how each type fulfills the same contract but with its own behavior!
In your main file, create a book and a movie using the two inputs provided, then print their descriptions on separate lines.
Your output should follow this format:
Book: {title}
Film: {name}For example, with inputs 1984 and Inception:
Book: 1984
Film: InceptionYou will receive two inputs: a book title and a movie name.
Cheat sheet
To implement a trait for a struct, use the impl TraitName for StructName syntax:
trait Speak {
fn speak(&self) -> String;
}
struct Dog {
name: String,
}
impl Speak for Dog {
fn speak(&self) -> String {
format!("{} says: Woof!", self.name)
}
}
Multiple types can implement the same trait with different behaviors:
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex says: Woof!
println!("{}", cat.speak()); // Whiskers says: Meow!
This enables polymorphism in Rust—different types sharing the same interface with unique implementations.
Try it yourself
mod describable;
mod items;
use describable::Describable;
use items::{Book, Movie};
fn main() {
// Read inputs
let mut title = String::new();
std::io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
// TODO: Create a Book instance with the title
// TODO: Create a Movie instance with the name
// TODO: Print the description of the book
// TODO: Print the description of the movie
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Methods and Behavior
Intro Implementation BlocksThe Self ParameterMutable MethodsAssociated FunctionsMultiple Implementation BlocksMethod ChainingRecap - Rectangle Actions4Project: Virtual Pet
Defining the PetFeeding the Pet7Standard Traits
The Debug TraitThe Display TraitClone and CopyEquality TraitsRecap - Printable Point10Project: Document System
The Draw TraitText Component2Encapsulation and Modules
Modules BasicsThe Public KeywordPrivate FieldsGettersSettersRecap - Secure Locker5Generics
Generic StructsGeneric MethodsMultiple Generic TypesGeneric FunctionsRecap - Coordinate Point8Traits as Bounds
Trait Bounds SyntaxMultiple BoundsThe Where ClauseReturning Types with TraitsRecap - Generic Printer11Design Patterns in Rust
Newtype PatternCompositionThe Drop TraitFrom and IntoRecap - Smart Pointer Mock3Advanced Enums
Enums with DataMethods on EnumsMatching Data VariantsThe Option Enum RevisitedRecap - Shape Enum6Traits Definition
What is a Trait?Implementing TraitsDefault ImplementationsOverriding DefaultsTraits with ParametersRecap - Media Player