trait Summary {
fn summarize(&self) -> String;
fn summarize_author(&self) -> String;
fn default_summary(&self) -> String {
format!("(Read more from {}...)", self.summarize_author())
}
}
struct NewsArticle {
headline: String,
location: String,
author: String,
content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
fn summarize_author(&self) -> String {
self.author.clone()
}
}
struct Tweet {
username: String,
content: String,
reply: bool,
retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
fn summarize_author(&self) -> String {
self.username.clone()
}
}
fn notify<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
let mut largest = list[0];
for &item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
impl Point<f32> {
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
struct Container<T, U> {
first: T,
second: U,
}
impl<T, U> Container<T, U> {
fn new(first: T, second: U) -> Self {
Self { first, second }
}
fn mix<V, W>(self, other: Container<V, W>) -> Container<T, W> {
Container {
first: self.first,
second: other.second,
}
}
}
trait Drawable {
fn draw(&self);
}
struct Circle {
radius: f64,
}
impl Drawable for Circle {
fn draw(&self) {
println!("Drawing circle with radius {}", self.radius);
}
}
struct Rectangle {
width: f64,
height: f64,
}
impl Drawable for Rectangle {
fn draw(&self) {
println!("Drawing rectangle {}x{}", self.width, self.height);
}
}
fn draw_shapes(shapes: &Vec<Box<dyn Drawable>>) {
for shape in shapes {
shape.draw();
}
}
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < 5 {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
fn blanket_impls() {
trait ToString {
fn to_string(&self) -> String;
}
impl<T: std::fmt::Display> ToString for T {
fn to_string(&self) -> String {
format!("{}", self)
}
}
let s = 3.to_string();
println!("{}", s);
}
fn trait_bounds() {
fn print_debug<T: std::fmt::Debug>(item: T) {
println!("{:?}", item);
}
fn compare<T: PartialOrd>(a: T, b: T) -> bool {
a > b
}
print_debug(vec![1, 2, 3]);
println!("5 > 3: {}", compare(5, 3));
}
fn multiple_trait_bounds() {
fn process<T: std::fmt::Display + Clone>(item: T) {
let cloned = item.clone();
println!("{}", cloned);
}
process(String::from("hello"));
}
fn where_clauses<T, U>(t: &T, u: &U) -> i32
where
T: std::fmt::Display + Clone,
U: Clone + std::fmt::Debug,
{
42
}
fn main() {
let article = NewsArticle {
headline: String::from("Penguins win the Stanley Cup Championship!"),
location: String::from("Pittsburgh, PA, USA"),
author: String::from("Iceburgh"),
content: String::from("..."),
};
notify(&article);
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
};
notify(&tweet);
let numbers = vec![34, 50, 25, 100, 65];
println!("Largest: {}", largest(&numbers));
let float_point = Point { x: 3.0, y: 4.0 };
println!("Distance: {}", float_point.distance_from_origin());
let shapes: Vec<Box<dyn Drawable>> = vec![
Box::new(Circle { radius: 5.0 }),
Box::new(Rectangle { width: 10.0, height: 20.0 }),
];
draw_shapes(&shapes);
let mut counter = Counter::new();
while let Some(i) = counter.next() {
println!("Counter: {}", i);
}
blanket_impls();
trait_bounds();
multiple_trait_bounds();
}