2021-08-25
pub trait Summary {
fn summarize(&self) -> String;
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{} by {} ({})", self.headline, self.author, self.location)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
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());
}
pub fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
pub fn notify_2<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
// Convenient
// The following could receive two different type implementing Summary
pub fn notify_3a(item1: &impl Summary, item2: &impl Summary) {}
// If we wanted to force both param to have the same type
pub fn notify_3b<T: Summary>(item1: &T, item2: &T) {}
// Specifying multiple trait bound with the +Syntax
pub fn notify_4a(item: &(impl Summary + Display)) {}
pub fn notify_4b<T: Summary + Display>(item: &T) {}
// Clearer Trait bound with where clause
fn somefunction_a<T: Display + Clone, U: Clone + Display>(t: &T, u: &U) -> i32 {
10
}
// Could be change for:
//---------------------
fn somefunction_b<T, U>(t: &T, u: &U) -> i32
where
T: Display + Clone,
U: Clone + Display,
{
10
}
// Returning type that implement traits
fn return_summarizable() -> impl Summary {
Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
}
}
// using trait bound to conditionnaly implement methods
use std::fmt::Display;
struct Pair<T> {
x: T,
y: T,
}
impl<T> Pair<T> {
fn new(x: T, y: T) -> Self {
Self { x, y }
}
}
impl<T: Display + PartialOrd> Pair<T> {
fn cmp_display(&self) {
if self.x >= self.y {
println!("The largest member is x = {}", self.x);
} else {
println!("The largest member is y = {}", self.y);
}
}
}
// We can implement a trait for any type that implements another trait.
// blanket implementations
impl<T: Display> ToString for T {
// --snip--
}
let s = 3.to_string();