Skip to content

Latest commit

 

History

History
156 lines (115 loc) · 2.41 KB

16.Generics.md

File metadata and controls

156 lines (115 loc) · 2.41 KB

📌 Generics in Rust


We use generics to create definitions for items like function signatures or structs, which we can then use with many different concrete data types. Generics allow you to write flexible, reusable code for multiple data types without duplicating logic.


🔹 1. Function with Duplicated Logic

fn main(){
  let bigger = largest_i32(1,2);
  let bigger_char = largets_char('a', 'b');
  println!("{}", bigger);
  println!("{}", bigger_char);
}

fn largest_i32(a: i32, b: i32) -> i32 {
  if a > b {
    a
  } else {
    b
  }
}

fn largest_char(a: char, b: char) -> char {
  if a > b {
    a
  } else {
    b
  }
}

❌ Problem: Repeated logic for different types


🔹 2. Function using Generics

fn largest<T: std::cmp::PartialOrd>(a: T, b: T) -> T {
    if a > b {
      a
    } else {
      b
    }
}

✅ Works for any type that implements PartialOrd (for comparison)


🔹 3. Generics in Structs

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

fn main() {
    let int_point = Point { x: 5, y: 10 };
    let float_point = Point { x: 1.0, y: 4.0 };
}

✅ Point<i32> and Point<f64> are two different concrete types generated from the same generic struct.


🔹 4. Generics in Structs with Different Types

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

fn main() {
    let p = MixPoint { x: 5, y: 3.2 };
}

✅ You can use multiple generic parameters in a struct.


🔹 5. Generics in Enums

enum Option<T> {
    Some(T),
    None,
}

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

✅ Option and Result are built-in enums that use generics.


🔹 6. Generics in Method Definitions

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

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

✅ You can implement methods on generic structs using the same generic type.


🔹 7. Mixing Generics in Methods

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,
        }
    }
}

✅ Combine fields from different points into a new one with mixed types.


💡 Generics are monomorphized at compile-time:

  • Rust generates a concrete version of your generic function/struct for each type used
  • No runtime cost!