Traits have to be brought into scope as well as the types to get the additional trait methods:
use aggregator::{Summary, Tweet}; // IMPORTANT!
fn main() {
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from(
"of course, as you probably already know, people",
),
reply: false,
retweet: false,
};
println!("1 new tweet: {}", tweet.summarize());
}
The impl Trait
syntax works for straightforward cases but is actually syntax sugar for a longer form known as a trait bound; it looks like this:
pub fn notify<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
We can use trait bounds to specify that a generic type can be any type that has certain behavior.
One can implement a trait on a type only if at least one of the trait or the type is local to our crate.
This restriction is part of a property of programs called coherence, and more specifically the orphan rule, so named because the parent type is not present. This rule ensures that other people’s code can’t break your code and vice versa.
Note that it isn’t possible to call the default implementation from an overriding implementation of that same method.
One can only use impl Trait
if you’re returning a single type, so returning different types with impl Trait
won’t compile. This is different from Golang’s interfaces, which allow such behavior.
However, “Using Trait Objects That Allow for Values of Different Types” section of Chapter 17 will discuss how to implement such behavior with trait objects.
TLDR: Implementations of a trait on any type that satisfies the trait bounds. This enables layered trait implementation that make indirectly use some basic utility (not necessarily) methods possible.
For example, the standard library implements the ToString
trait on any type that implements the Display
trait. The impl
block in the standard library looks similar to this code:
impl<T: Display> ToString for T {
// --snip--
}
Because the standard library has this blanket implementation, we can call the to_string
method defined by the ToString
trait on any type that implements the Display
trait. For example, we can turn integers into their corresponding String
values like this because integers implement