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:
pub trait Summary {
fn summarize(&self) -> String;
}
To implement a trait on a concrete type, we use the syntax impl TraitName for TypeName:
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>:
pub fn notify<T: Summary>(item: &T) {
println!("Notification: {}", item.summarize());
}
Alternatively, for more complex signatures, we can use the where clause:
pub fn notify_advanced<T>(item: &T)
where
T: Summary
{
println!("Notification: {}", item.summarize());
}
Try it yourself
Exercise 1: The Summary Trait
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.
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
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().
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
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).
Show hint
Define the `Area`trait and the`Circle`struct. Implement`area(&self)` using the circle area formula.
Solution available after 3 attempts