Generics, Traits & Lifetimes

Generics, traits, and lifetimes are Rust’s compile-time abstraction toolkit: they remove duplication, state behavioral contracts, and prove borrowed data remains valid.

Concepts

Patterns

Antipatterns

Example

use std::fmt::Display;
 
fn announce_largest<'a, T>(left: &'a T, right: &'a T, label: impl Display) -> &'a T
where
    T: PartialOrd,
{
    println!("{label}");
    if left >= right { left } else { right }
}
 
fn main() {
    let a = 10;
    let b = 20;
    assert_eq!(*announce_largest(&a, &b, "numbers"), 20);
}

Reading Path

Start with Generics, Traits, and Lifetimes. Then read Trait Bounds, Where Clauses, and Lifetime Elision to understand signatures. Move to Associated Types, Generic Associated Types, and Blanket Implementations when designing reusable traits. Finish with Coherence and the Orphan Rule, Use a Newtype to Implement Foreign Traits, and Sealed Traits before publishing trait-heavy APIs.

See also

Ownership · Borrowing · References · The Iterator Trait · Dynamically Sized Types · Fully Qualified Syntax · Newtype Pattern · Zero-Cost Abstractions

Sources