Rust Traits

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 Trait for simple cases, trait bounds for complex.
  • derive is 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.