Advanced
Traits and Generics
Write reusable code with Rust traits (like interfaces) and generic types.
Traits
Traits define shared behavior. They're similar to interfaces in other languages but more powerful.
You can implement traits for any type, even types you didn't define.
Generics
Write functions and types that work with multiple types while preserving type safety.
Trait Bounds
Constrain generic types to those that implement specific traits.
Common Standard Traits
Display: How to format for printing ({})Debug: How to format for debugging ({:?})Clone: Deep copyCopy: Stack copy (implicit)Iterator: Custom iterators
Example
rust
use std::fmt;
// Define a trait
trait Summary {
fn summarize(&self) -> String;
fn author(&self) -> String;
// Default implementation
fn preview(&self) -> String {
format!("{}... - {}", &self.summarize()[..50.min(self.summarize().len())], self.author())
}
}
struct Article {
title: String,
content: String,
author: String,
}
struct Tweet {
username: String,
content: String,
}
impl Summary for Article {
fn summarize(&self) -> String { self.content.clone() }
fn author(&self) -> String { self.author.clone() }
}
impl Summary for Tweet {
fn summarize(&self) -> String { self.content.clone() }
fn author(&self) -> String { format!("@{}", self.username) }
}
// Generic function with trait bound
fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.preview());
}
// Generic with where clause
fn compare_summaries<T, U>(t: &T, u: &U) -> String
where
T: Summary + fmt::Debug,
U: Summary,
{
format!("{} vs {}", t.summarize(), u.summarize())
}
// Generic struct
struct Pair<T> {
first: T,
second: T,
}
impl<T: PartialOrd + fmt::Display> Pair<T> {
fn largest(&self) -> &T {
if self.first >= self.second { &self.first } else { &self.second }
}
}
fn main() {
let article = Article {
title: String::from("Rust is Amazing"),
content: String::from("Rust provides memory safety without GC."),
author: String::from("Alice"),
};
let tweet = Tweet {
username: String::from("rustlang"),
content: String::from("Exciting news about Rust 2024!"),
};
notify(&article);
notify(&tweet);
let pair = Pair { first: 5, second: 10 };
println!("Largest: {}", pair.largest()); // 10
}Try it yourself — RUST