Generics allow us to replace specific types with a placeholder that represents multiple types to remove code duplication.

Functions:

fn some_func<T>(list: &[T]) -> &T {}

Structs:

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

Enums:

enum Option<T> {
    Some(T),
    None,
}
 
enum Result<T, E> {
    Ok(T),
    Err(E),
}

Methods:

struct Point<T> {
    x: T,
    y: T,
}
 
impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

They can mix up like:

struct Point<X1, Y1> {
    x: X1,
    y: Y1,
}
 
impl<X1, Y1> Point<X1, Y1> {
    fn mixup<X2, Y2>(self, other: Point<X2, Y2>) -> Point<X1, Y2> {
        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);
}

The purpose of this example is to demonstrate a situation in which some generic parameters are declared with impl and some are declared with the method definition. Here, the generic parameters X1 and Y1 are declared after impl because they go with the struct definition. The generic parameters X2 and Y2 are declared after fn mixup, because they’re only relevant to the method.

You might be wondering whether there is a runtime cost when using generic type parameters. The good news is that using generic types won’t make your program run any slower than it would with concrete types.

Rust accomplishes this by performing monomorphization of the code using generics at compile time. Monomorphization is the process of turning generic code into specific code by filling in the concrete types that are used when compiled.

Generic Type Parameters, Trait Bounds, and Lifetimes Together

use std::fmt::Display;
 
fn longest_with_an_announcement<'a, T>(
    x: &'a str,
    y: &'a str,
    ann: T,
) -> &'a str
where
    T: Display,
{
    println!("Announcement! {ann}");
    if x.len() > y.len() {
        x
    } else {
        y
    }
}