Skip to main content
eLearner.app
Module 5 · Lesson 2 of 210/14 in the course~15 min
Module lessons (2/2)

Traits and Trait Bounds

Traits define the behavior that a particular type has and can share with other types. We can use traits to define a set of methods that represent a certain common functionality or interface, similar to interfaces in other programming languages.

Trait bounds allow us to specify that a generic type must implement a specific trait, ensuring that the required methods are available at compile time.


Defining and Implementing a Trait

To define a trait, we use the trait keyword followed by the signatures of the methods that implementing types must define:

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

To implement a trait on a concrete type, we use the syntax impl TraitName for TypeName:

Code
pub struct NewsArticle {
    pub headline: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}", self.headline)
    }
}

Trait Bounds

When writing generic functions, we can constrain the type parameters to ensure they implement a specific trait. The standard syntax is <T: Trait>:

Code
pub fn notify<T: Summary>(item: &T) {
    println!("Notification: {}", item.summarize());
}

Alternatively, for more complex signatures, we can use the where clause:

Code
pub fn notify_advanced<T>(item: &T)
where
    T: Summary
{
    println!("Notification: {}", item.summarize());
}

Try it yourself

Exercise 1: The Summary Trait

Exercise#rust.m5.l2.e1
Attempts: 0Loading…

Define a trait named Summary containing the method signature fn summarize(&self) -> String;. Next, define a struct NewsArticle with a headline field of type String and implement the Summary trait for it so that the summarize method returns the value of the headline field.

Loading editor…
Show hint

Define the `Summary`trait and the`NewsArticle`struct. Implement with`impl Summary for NewsArticle`cloning the field`self.headline.clone()`.

Solution available after 3 attempts

Exercise 2: Trait Bounds with print_summary

Exercise#rust.m5.l2.e2
Attempts: 0Loading…

Based on the code from the previous exercise, define a generic function named print_summary<T> that accepts a parameter item of type &T. Apply a trait bound so that T must implement the Summary trait. Inside the function, print the result returned by item.summarize().

Loading editor…
Show hint

Use the signature `fn print_summary<T: Summary>(item: &T)`and invoke`item.summarize()`inside the`println!`.

Solution available after 3 attempts

Exercise 3: Area Calculation using Traits

Exercise#rust.m5.l2.e3
Attempts: 0Loading…

Define a trait named Area with the method fn area(&self) -> f64;. Create a struct Circle containing a radius field of type f64, and implement the Area trait for it by calculating the area (formula: radius * radius * 3.14159).

Loading editor…
Show hint

Define the `Area`trait and the`Circle`struct. Implement`area(&self)` using the circle area formula.

Solution available after 3 attempts