Lesson 15 of 20

Traits

Traits

Traits define shared behavior. They are similar to interfaces in other languages.

Defining a Trait

trait Summary {
    fn summarize(&self) -> String;

    // Default implementation
    fn author(&self) -> String {
        String::from("(anonymous)")
    }
}

Implementing a Trait

struct Article {
    title: String,
    content: String,
}

impl Summary for Article {
    fn summarize(&self) -> String {
        format!("{}: {}", self.title, &self.content[..50])
    }
}

Trait Bounds

Require that a type implements a trait:

fn notify(item: &impl Summary) {
    println!("Breaking news! {}", item.summarize());
}

// Equivalent with where clause:
fn notify<T: Summary>(item: &T) {
    println!("Breaking news! {}", item.summarize());
}

Multiple Trait Bounds

fn print_and_summarize(item: &(impl Summary + std::fmt::Display)) {
    println!("{} — {}", item, item.summarize());
}

impl Trait in Return Position

fn make_summary() -> impl Summary {
    Article { title: String::from("..."), content: String::from("...") }
}

Common Standard Traits

  • Display — for {} formatting
  • Debug — for {:?} formatting (can #[derive(Debug)])
  • Clone — for .clone()
  • PartialOrd / Ord — for comparison
  • Iterator — for .next() iteration

Your Task

Define an Area trait with:

  • area(&self) -> f64
  • larger_than(&self, other: &impl Area) -> bool (default implementation comparing areas)

Implement Area for Circle { radius: f64 } and Square { side: f64 }.

Also write print_area(shape: &impl Area) -> f64 that returns the area.

Rust (Miri) loading...
Loading...
Click "Run" to execute your code.