Introduction
Rust has no classes or inheritance. Instead, it uses traits to define shared behavior that different types can implement. A trait is a collection of method signatures that describe some functionality a type can provide. Traits let you write code that works with any type implementing a particular behavior, enabling polymorphism without an inheritance hierarchy.
Cricket analogy: Rust skips class hierarchies and instead uses traits, like how the ICC doesn't require every all-rounder to descend from a single 'master cricketer' class — Kohli, Jadeja, and Bumrah each just need to prove they can 'bat', 'bowl', or 'field' on demand.
Syntax
trait Summary {
fn summarize(&self) -> String;
}
struct Article {
headline: String,
body: String,
}
impl Summary for Article {
fn summarize(&self) -> String {
format!("{}: {}", self.headline, &self.body[..20])
}
}Explanation
The trait Summary block declares a method signature, summarize, that any implementing type must provide. The impl Summary for Article block then supplies the actual implementation for the Article struct. Any type can implement any trait as long as either the type or the trait is defined locally in your crate (the orphan rule). Multiple types can implement the same trait, each with its own logic, and a type can implement many traits.
Cricket analogy: The trait Summary is like the BCCI mandating every captain must be able to 'give a post-match interview'; impl Summary for Article is Rohit Sharma's team specifically writing how their captain delivers that interview, and since Article is your own crate's type, there's no orphan-rule violation.
Example
trait Summary {
fn summarize(&self) -> String;
}
struct Tweet {
username: String,
content: String,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("@{}: {}", self.username, self.content)
}
}
fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
fn main() {
let tweet = Tweet {
username: String::from("rustlang"),
content: String::from("Traits are powerful!"),
};
notify(&tweet);
}Output
Breaking news! @rustlang: Traits are powerful!Key Takeaways
- Traits define shared behavior via method signatures, similar to interfaces.
- Rust has no classes or inheritance; traits plus composition are the idiom.
- The orphan rule requires the trait or the type to be local to your crate.
- The
impl Traitsyntax in function parameters accepts any type implementing that trait. - A single type can implement many different traits.
Practice what you learned
1. What does a Rust trait primarily define?
2. How do you implement a trait for a struct named `Point`?
3. Which statement about Rust is correct?
4. What is the orphan rule in the context of traits?
5. What does `fn notify(item: &impl Summary)` accept?
Was this page helpful?
You May Also Like
Generics in Rust
Generics let you write functions, structs, and enums that work over many types while remaining zero-cost at runtime.
Trait Objects and Dynamic Dispatch in Rust
Trait objects like `dyn Trait` enable runtime polymorphism for heterogeneous collections, at the cost of dynamic dispatch.
Default Trait Implementations in Rust
Trait methods can provide a default body that implementers may use as-is or override with custom behavior.
Structs in Rust
Structs let you group related values into a single named type with fields you access by name.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics