100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Rust

Generics in Rust

Generics let you write functions, structs, and enums that work over many types while remaining zero-cost at runtime.

Traits & GenericsIntermediate9 min readJul 8, 2026
Analogies

Introduction

Generics allow you to write code that operates on abstract types rather than one concrete type, avoiding duplication. A function or struct can be parameterized with a type placeholder, commonly written T, and the compiler generates specialized versions for each concrete type actually used — a process called monomorphization. This means generics have no runtime overhead compared to hand-written type-specific code.

🏏

Cricket analogy: Generics let you write one largest_score<T> function that works for both ODI and Test match scores instead of duplicating it; the compiler monomorphizes a specialized version for each concrete score type used, at no runtime cost.

Syntax

rust
fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

struct Point<T> {
    x: T,
    y: T,
}

Explanation

The <T: PartialOrd> syntax declares a generic type parameter T with a trait bound, meaning T must implement PartialOrd so that values can be compared with >. Trait bounds constrain which types are valid, letting the compiler check correctness at compile time. Generic structs like Point<T> store fields of a type chosen when the struct is instantiated, e.g. Point<i32> or Point<f64>. Multiple bounds can be combined, such as <T: Display + Clone>, requiring T to satisfy both traits.

🏏

Cricket analogy: The bound <T: PartialOrd> is like requiring any stat type to be comparable so you can rank Kohli's average against Root's with >; a generic ScoreCard<T> then holds a runs field typed as i32 or f64 when instantiated.

Example

rust
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];
    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

fn main() {
    let numbers = vec![34, 50, 25, 100, 65];
    let result = largest(&numbers);
    println!("The largest number is {}", result);

    let chars = vec!['y', 'm', 'a', 'q'];
    let result = largest(&chars);
    println!("The largest char is {}", result);
}

Output

text
The largest number is 100
The largest char is y

Key Takeaways

  • Generics parameterize functions, structs, and enums over abstract types.
  • Trait bounds like <T: PartialOrd> restrict which types satisfy the generic constraint.
  • Monomorphization generates specialized code per concrete type, making generics zero-cost.
  • Multiple bounds can be combined with +, e.g. <T: Display + Clone>.
  • Generic code is checked for correctness entirely at compile time.

Practice what you learned

Was this page helpful?

Topics covered

#Rust#RustProgrammingStudyNotes#Programming#GenericsInRust#Generics#Syntax#Explanation#Example#StudyNotes#SkillVeris