Generics

Contents

Generics#

<T> declares a type parameter; the caller fills it (or inference does).

Generic function.

fn first<T>(xs: &[T]) -> Option<&T> {
    xs.first()
}

Generic struct and a generic impl block.

struct Container<T> { value: T }

impl<T: Clone> Container<T> {
    fn duplicate(&self) -> (T, T) {
        (self.value.clone(), self.value.clone())
    }
}

Constraints (T: Trait) describe what T must support.

fn print_all<T: std::fmt::Display>(xs: &[T]) {
    for x in xs { println!("{x}"); }
}

where clauses are the alternative when constraints get long.

fn merge<T>(a: T, b: T) -> T
where T: std::ops::Add<Output = T>,
{
    a + b
}

References#

  • OOP for trait definitions that drive constraints.

  • Trait objects for dynamic dispatch via dyn Trait.