20.8 Generics Instead of Traditional OOP

In many languages, you might reach for inheritance to share logic across multiple types. Rust encourages generics, which offer compile-time polymorphism. Rather than storing data in a “base class pointer,” Rust monomorphizes generic code for each concrete type, often yielding both performance benefits and clarity.

Example: Generic Function

fn print_elements<T: std::fmt::Debug>(data: &[T]) {
    for element in data {
        println!("{:?}", element);
    }
}

fn main() {
    let nums = vec![1, 2, 3];
    let words = vec!["hello", "world"];
    print_elements(&nums);
    print_elements(&words);
}

By bounding T with std::fmt::Debug, the compiler can generate specialized versions of print_elements for any type that meets this requirement.