Skip to content

Generics

Updated
17 Sept 2026
2 min read
0 sections
Page 18 of 18
Rust
  • Generics are a way to define functions, structs, enums, and methods that work with any type
  • Generics allows us to reduce code duplication
  • Does not affect performance because Rust uses monomorphization to create specific implementations of generic code at compile time
  • T is a generic type parameter
rust
fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let largest = get_largest(number_list);

    println!("The largest number is {}", largest);
}

fn get_largest<T>(number_list: Vec<T>) -> T {
    let mut largest = number_list[0];

    for &number in number_list.iter() {
        if number > largest {
            largest = number;
        }
    }

    largest
}
Error:
binary operation > cannot be applied to type T
rust
fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let largest = get_largest(number_list);

    println!("The largest number is {}", largest);
}

fn get_largest<T>(number_list: Vec<T>) -> T {
    let mut largest = number_list[0];

    for &number in number_list.iter() {
        if number > largest {
            largest = number;
        }
    }

    largest
}
rust
fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let largest = get_largest(number_list);

    println!("The largest number is {}", largest);
}

fn get_largest<T: PartialOrd + Copy>(number_list: Vec<T>) -> T {
    let mut largest = number_list[0];

    for &number in number_list.iter() {
        if number > largest {
            largest = number;
        }
    }

    largest
}
  • PartialOrd trait is used to compare values
  • Copy trait is used to copy values
rust
struct Point<T> {
    x: T,
    y: T,
}
fn main() {
    let integer = Point { x: 5, y: 10 };
    let float = Point { x: 1.0, y: 4.0 };

    println!("integer.x = {}", integer.x);
    println!("float.x = {}", float.x);
}
  • Point struct with generic type T
  • Problem: both x and y must have the same type
rust
struct Point<T, U> {
    x: T,
    y: U,
}

fn main() {
    let integer = Point { x: 5, y: 1.0 };
    let float = Point { x: 1.0, y: 4.0 };

    println!("integer.x = {}", integer.x);
    println!("float.x = {}", float.x);
}
  • Option{:rust} & Result{:rust} enums are generics too
rust
struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

impl Point<f64> {
    fn y(&self) -> &f64 {
        &self.y
    }
}

fn main() {
    let p = Point { x: 5, y: 10 };

    p.x();

    let p = Point { x: 5.0, y: 10.0 };
    p.y();

    println!("p.x = {}", p.x());
}
  • y(){:rust} method is only available for Point<f64>{:rust}
rust
struct Point<T, U> {
    x: T,
    y: U,
}

impl<T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point {
            x: self.x,
            y: other.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 5, y: 10.4 };
    let p2 = Point { x: "Hello", y: 'c' };

    let p3 = p1.mixup(p2);

    println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}
  • mixup method is used to mix two Point instances
  • impl<T, U> Point<T, U>{:rust} is used to define methods for Point struct
  • fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W>{:rust} is a method that takes another Point instance and returns a new Point{:rust} instance