Generic Code
What if you want a function that works with i32 AND f64 AND String? Instead of writing separate functions for each type, you can write one using generics!
The Problem
Without generics, you'd need duplicate functions:
That's a lot of repetition!
Generic Functions
A generic function uses a type parameter (usually T) that stands for "any type":
The <T: std::fmt::Display> means "T can be any type, as long as it can be printed with {}".
Generic Structs
Structs can also use generics:
One Wrapper struct works with any type!
Multiple Type Parameters
You can have more than one generic type:
Trait Bounds
When you need your generic type to have certain abilities, use trait bounds:
T: PartialOrd means "T must support comparison operators like >=".
Multiple Trait Bounds
Use + to require multiple traits:
Generic Methods
You can add methods to generic structs:
Where Clauses
For complex bounds, use where for cleaner code:
Summary
| Concept | What it does |
|---|---|
fn name<T>(x: T) | Generic function with type parameter |
struct Name<T> { field: T } | Generic struct |
T: Display | Trait bound — T must implement Display |
T: PartialOrd + Display | Multiple trait bounds |
where T: Display | Where clause for cleaner bounds |
impl<T> Name<T> { ... } | Methods on generic struct |
Now let's practice writing generic code!