🚀
10. Traits
Languages

Traits

pub struct NewsArticle {

Mar 202510 min read

Traits

pub struct NewsArticle {
    pub headline: String,
    pub author: String,
    pub content: String,
}
 
impl NewsArticle {
    fn summarize(&self) -> String {
        format!("{} | by {}", self.headline, self.author)
    }
}
 
pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}
 
impl Tweet {
    fn summarize(&self) -> String {
        format!("{}, @ {}", self.content, self.username)
    }
}
 
fn main() {
    let tweet = Tweet {
        username: String::from("@johndoe"),
        content: String::from("Hello, World !"),
        reply: false,
        retweet: false,
    };
 
    let article = NewsArticle {
        headline: String::from("Breaking News"),
        author: String::from("John Doe"),
        content: String::from("This is a breaking news article"),
    };
 
    println!("1 new tweet: {}", tweet.summarize());
    println!("New article available: {}", article.summarize());
}
Execution Output
$ cargo run

1 new tweet: @johndoe, by Hello, World !
New article available: Breaking News, by John Doe (This is a breaking news article)
  • Traits are used to define shared behavior in an abstract way
  • trait keyword is used to define a trait
pub struct NewsArticle {
    pub headline: String,
    pub author: String,
    pub content: String,
}
 
impl Summary for NewsArticle {}
 
pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}
 
impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("{}, by {}", self.username, self.content)
    }
}
 
pub trait Summary {
    fn summarize(&self) -> String {
        String::from("(Read more...)")
    }
}
 
fn main() {
   // --snip--
}
 
Execution Output
$ cargo run

1 new tweet: @johndoe, by Hello, World !
New article available: (Read more...)
pub trait Summary {
    fn summarize_author(&self) -> String;
 
    fn summarize(&self) -> String {
        format!("(Read more from {}...)", self.summarize_author())
    }
}
 
impl Summary for NewsArticle {
    fn summarize_author(&self) -> String {
        format!("@{}", self.author)
    }
}
 
impl Summary for Tweet {
    fn summarize_author(&self) -> String {
        format!("@{}", self.username)
    }
 
    fn summarize(&self) -> String {
        format!("{}, by {}", self.username, self.content)
    }
}
Execution Output
$ cargo run

1 new tweet: @johndoe, by Hello, World !
New article available: (Read more from @John Doe...)
  • summarize_author method is added to the Summary trait, which is implemented by both NewsArticle and Tweet structs

Traits as Parameters

pub fn notify(item: &impl Summary) {
    println!("Breaking news! {}", item.summarize());
}
 
fn main() {
    // --snip--
 
    notify(&tweet);
    notify(&article);
}
Execution Output
$ cargo run

Breaking news! @johndoe, by Hello, World !
Breaking news! (Read more from @John Doe...)
  • impl Summary is used as a parameter type for the notify function
  • This allows the function to accept any type that implements the Summary trait

Trait Bound Syntax

pub fn notify<T: Summary>(item: &T) {
    println!("Breaking news! {}", item.summarize());
}
 
fn main() {
    // --snip--
 
    notify(&tweet);
    notify(&article);
}
  • T: Summary is a trait bound, which specifies that T must implement the Summary trait

Multiple Trait Bounds

pub fn notify<T: Summary + Display>(item: &T) {
    println!("Breaking news! {}", item.summarize());
    println!("Breaking news! {}", item);
}
 
fn main() {
    // --snip--
 
    notify(&tweet);
    notify(&article);
}
  • T: Summary + Display specifies that T must implement both the Summary and Display traits

Where Clauses

  • Specifing multiple trait bounds could hinder code readablity, like
fn some_function<T: Display + Clone, U : Clone + Debug>(t: &T, u: & U) -> i32 {}
  • where clause is used to specify trait bounds, which makes the function signature more readable
pub fn notify<T>(item: &T)
where T: Summary + Display,
      U: Clone + Debug
{
    println!("Breaking news! {}", item.summarize());
    println!("Breaking news! {}", item);
}

Returning Types that Implement Traits

fn returns_summarizable() -> impl Summary {
    Tweet {
        username: String::from("@johndoe"),
        content: String::from("Hello, World !"),
        reply: false,
        retweet: false,
    }
}
 
fn main() {
    let tweet = returns_summarizable();
    println!("1 new tweet: {}", tweet.summarize());
}
Execution Output
$ cargo run

1 new tweet: @johndoe, by Hello, World !
  • impl Summary is used as a return type, which specifies that the function will return a type that implements the Summary trait

Conditional Implement Methods

  • Methods can be implemented conditionally based on trait bounds
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);
        }
    }
}
 
fn main() {
    let pair = Pair::new(5, 10);
    pair.cmp_display();
}
  • PartialOrd and Display traits are implemented for the Pair struct, which allows the cmp_display method to be called

Blanket Implementations

  • Implementing a trait for any type that implements another trait
impl<T: Display> ToString for T {
    fn to_string(&self) -> String {
        format!("{}", self)
    }
}

© 2026 Driptanil Datta. All rights reserved.

Software Developer & Engineer

Disclaimer:The content provided on this blog is for educational and informational purposes only. While I strive for accuracy, all information is provided "as is" without any warranties of completeness, reliability, or accuracy. Any action you take upon the information found on this website is strictly at your own risk.

Copyright & IP:Certain technical content, interview questions, and datasets are curated from external educational sources to provide a centralized learning resource. Respect for original authorship is maintained; no copyright infringement is intended. All trademarks, logos, and brand names are the property of their respective owners.

System Operational

Built with Love ❤️ | Last updated: Mar 16 2026