Generics in Rust
In this lesson, you will learn about generics in Rust. Generics allow you to write flexible, reusable code that works with many data types without duplicating logic.
Generics are a core feature of Rust and are widely used in the standard library, especially with traits and collections.
What Are Generics?
Generics let you write code that operates on any type, instead of a single concrete type.
They are represented using type parameters, usually written as <T>.
This makes code more reusable and easier to maintain.
Why Use Generics?
Without generics, you would need to write the same function multiple times for different data types.
Generics solve this problem by allowing one implementation to handle many types.
Generic Functions
You can define a generic function by specifying a type parameter inside angle brackets.
fn print_value(value: T) {
println!("Value received");
}
Here, T represents any type.
Using Generics with Parameters
You can pass generic values to functions just like normal parameters.
fn display(item: T) {
println!("Item displayed");
}
display(10);
display("Rust");
Generic Structs
Structs can also be generic, allowing them to store different data types.
struct BoxItem {
value: T,
}
let number_box = BoxItem { value: 5 };
let text_box = BoxItem { value: "Hello" };
The same struct definition works for multiple types.
Generic Methods
You can define methods on generic structs using impl<T>.
impl BoxItem {
fn get_value(&self) -> &T {
&self.value
}
}
Generics with Trait Bounds
Sometimes, you need generics to support only specific behaviors. This is done using trait bounds.
fn show(item: T) {
println!("{:?}", item);
}
This function only accepts types that implement the Debug trait.
Multiple Trait Bounds
You can require multiple traits using the + symbol.
fn process(item: T) {
let copy = item.clone();
println!("{:?}", copy);
}
Generics with Enums
Enums can also be generic.
Rust’s Option and Result are classic examples.
enum Wrapper {
Value(T),
Empty,
}
Performance of Generics
Rust uses a technique called monomorphization. This means generic code is compiled into specific versions for each type.
As a result, generics have zero runtime cost.
Why Generics Are Important
Generics allow you to:
- Write reusable code
- Avoid duplication
- Build flexible APIs
- Maintain high performance
📝 Practice Exercises
Exercise 1
Create a generic function that returns the value passed to it.
Exercise 2
Create a generic struct that stores two values.
Exercise 3
Write a generic function with a trait bound.
Exercise 4
Create a generic enum with two variants.
✅ Practice Answers
Answer 1
fn identity(value: T) -> T {
value
}
Answer 2
struct Pair {
first: T,
second: U,
}
Answer 3
fn print_debug(item: T) {
println!("{:?}", item);
}
Answer 4
enum Container {
Item(T),
None,
}
What’s Next?
In the next lesson, you will learn about Error Handling in Rust — including panic, recoverable errors, and best practices.