Traits define shared behaviour — similar to interfaces in other languages. A trait specifies what methods a type must have, and any type can implement any trait.
Defining a Trait
Rust
trait Summary {
fn summarize(&self) -> String;
}Implementing a Trait
Rust
struct Article {
title: String,
author: String,
content: String,
}
impl Summary for Article {
fn summarize(&self) -> String {
format!("{} — by {}", self.title, self.author)
}
}Traits as Parameters
Rust
fn notify(item: &impl Summary) {
println!("Breaking: {}", item.summarize());
}
// Equivalent with trait bound syntax
fn notify<T: Summary>(item: &T) {
println!("Breaking: {}", item.summarize());
}Multiple Trait Bounds
Rust
use std::fmt::{Display, Debug};
fn compare<T: Display + Debug>(a: &T, b: &T) {
println!("{a:?} vs {b:?}");
}Default Implementations
Rust
trait Greet {
fn greet(&self) -> String {
"Hello!".to_string() // default — can be overridden
}
}
struct User { name: String }
impl Greet for User {
fn greet(&self) -> String {
format!("Namaste, {}!", self.name)
}
}derive Macros
Automatically implement common traits:
Rust
#[derive(Debug, Clone, PartialEq)]
struct Point {
x: f64,
y: f64,
}| Trait | What it does |
|---|---|
Debug |
Enables {:?} formatting |
Clone |
Enables .clone() |
PartialEq |
Enables == and != |
Default |
Provides default values |
Tips
- Traits are Rust's interfaces — use them for polymorphism.
- Use
impl Traitfor simple cases, trait bounds for complex. deriveis your friend — it saves hours of boilerplate.- Keep traits small — one concept per trait.
🎉 You have completed the Rust course! The next step is to build something — a CLI tool, a web server, or a library.