# Traits This is used to defined shared behavior A *trait* defines the fnctionality a particular type has and can share with other tpyes. Traits are ued to define shared behavior in an abstract way. We can use *trait bounds* to specifty that a generic type can be any type that has certain behavior Note: Traits are similar to a feature often called *interfaces* in other languages, but there are some differences in Rust ## Defining a Trait A type's behavior consists of the methods we can call on that type Some types can share the same behavior if we can call the same methods on all of those types. Trait definitions are a way to gropu method singatures together to define a set of behaviors necessary to accomplish something. Here is an exmaple to lay this out lets say you have multiple structs that hold various kinds and amounts of text `NewsArticle` struct that holds a news story filed in a particular locaion `Tweet` that can have, at most, 280 characters along with metadata that indicates whether it was a new tweet, a retweet, or a reply to another tweet We want to make a meida aggregator library crate named `aggregator` that can display summaries of data that could be stored in a `NewsArticle` or `Tweet` In order to do this we need a summary from each type, this would be done by calling a `summarize` method on an instance Example definition of a trait for the above situation ```rust pub trait Summary { fn summarize(&self) -> String; } ``` Inside the trait named scope is where method signatures are defined After the method signature, instead of providing an implmentation within the curly brackets, you use a semicolon Each type implementing this trait must provide its own custom behavor for the body of the method The compliler will enfore that any type that has the `Summary` trait will havee the method `summarize` defined with this signature Note: a trait can habe multiple methods in its body, each method signature are listed one per line and each lne ends in a semicolon ## Implementing a Trait on a Type Now that the desirred signatures of the `Summary` trait's methods, we can implement it on the types in our media aggregator Here is an example where the trait is implmented for both `NewsArticle` and `Tweet` structs ```rust 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) } } ``` Implementing this is similar to implementing regular methods. The difference is after the `impl` we put the trait name we want to implement, then use the `for` keyword, then put the specify the name of the type we want to implement the trait for. In the `impl` block we put the method's singaure that the trait has defined, but instead of a semicolon you put the implementation with its behavior in curly braces. Now that the library has implemented thr `Summary` trait on `NewsArticle` and `Tweet`, users of the crate can call the trait methods on instances of `NewsArticle` and `Tweet` in the same way regular methods, the only difference is that you need to bring the trait into scope as well as the type Here is an example of how a binary crate could use our `aggregator` library crate ```rust use aggregator::{Summary, Tweet}; 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()); } ``` Other cates that depend on the `aggregator` crate can also bring the `Summary` trait into scope to implement `Summary` on their own type One restriction to note is that we can implement a trait on a type only if either the trait or the tpye, or both are local to your crate For example, you can implement standard library traits like `Display` on custom tpye like `Tweet` as part of our `aggregator` crate functionality because the type `Tweet` is local to our `aggregator` crate We could also implement `Summary` on `Vec` in our `aggregator` crate because the trait `Summary` is local to our `aggregator` crate You cant implement external trait on external types For example you cant implement `Display` trait on `Vec` within our aggregator create they are both defined in the std library which are both not local to our `aggregator` crate This restriction is part of a property called *coherence*, and more specifically the *orphan rule*, this is named becuase the parent type is not present This rule ensures that other people's code can't breake your code and vice versa. Without this rule the compiler could or would get confused about two implmentations of the same trait on the same type in tow different crates ## Default Implementations This is sometimes useful to have defualt behavior for some or all of the methods in a trait instead of requiring implementaitons for all method on every type. This could be overridden by implementation on the type itself of the trait with the speicific singature Here is an example of this ```rust pub trait Summary { fn summarize(&self) -> String { String::from("(Read more...)") } } ``` To use the defualt implementation to summarize instances of `NewArticel`, we specifiy an empty `impl` block with `impl Summary for NewsArticle {}` Even though `summarize` is not defined on `NewsArticle` directly we have a defualt implementation and we specified that `NewsArticle` implements the `Summary` trait The provided defualt implementation allows you to do something like this, even though the implemntation function scope is empty ```rust 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( "The Pittsburgh Penguins once again are the best \ hockey team in the NHL.", ), }; println!("New article available! {}", article.summarize()); ``` This still prints `New article available! (Read more...)` Default implmentations can call other methods in the smae trait, even if other methods don't have a default implementations. For example ```rust pub trait Summary { fn summarize_author(&self) -> String; fn summarize(&self) -> String { format!("(Read more from {}...)", self.summarize_author()) } } ``` This default implementation only requires the signuare in order to use, it relies that the implementation in the type, which the compiler ensures To use thus version of `Summary`, we only need to define `summarize_author` when we implement the trait on a type Because we have implemented `summarize_author`, the `Summary` trait has given the behavior of the `summarize` method without requiring us to write any more code Here is the use of the `summarize_author` trait method ```rust 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()); ``` This would print `1 new tweet: (Read more from @horse_ebooks...)` Note: it is impossible to call the default implementation from an overridden implementation of that same method ## Traits as Parameters