π¦ Rust Series 3: **Generics, Traits & Implementations**


β¨ Introduction
Welcome back to our Rust learning journey!
In our last post, we explored control flow, functions, and ownership. Today, we dive into three powerful concepts that make Rust both flexible and type-safe:
π Generics, Traits, and Implementations
π§ Generics in Rust
Generics let you write code that works with many different types while keeping Rustβs zero-cost abstraction promise.
// Generic function that works with any type implementing Add
fn sum_of_two_number<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
// Usage
let int_result = sum_of_two_number(20, 20);
let float_result = sum_of_two_number(20.20, 20.20);
π΄ Without generics, youβd have to write separate functions:
fn sum_u32(a: u32, b: u32) -> u32 {
a + b
}
fn sum_f32(a: f32, b: f32) -> f32 {
a + b
}
π¦ Structs & impl
Blocks
You add functionality to types in Rust using impl
.
struct Rect {
width: u32,
height: u32,
}
impl Rect {
fn area(&self) -> u32 {
self.width * self.height
}
}
// Usage
let rect = Rect { width: 20, height: 30 };
println!("Area: {}", rect.area());
π§± Generic Structs + Trait Bounds
Structs can be generic too, and we can add functionality using trait bounds.
struct RectWithGeneric<T> {
width: T,
height: T,
}
impl<T: std::ops::Add<Output = T> + Copy> RectWithGeneric<T> {
fn area(&self) -> T {
self.width + self.height
}
}
// Usage
let float_rect = RectWithGeneric { width: 20.1, height: 20.2 };
let int_rect = RectWithGeneric { width: 200, height: 200 };
π‘ Traits: Defining Shared Behavior
Traits are like interfaces in other languages β they define capabilities that types can implement.
// Display trait for printing
fn print<T: std::fmt::Display>(item: T) {
println!("{}", item);
}
// Ord trait for comparison
fn max<T: Ord>(a: T, b: T) -> T {
if a > b { a } else { b }
}
Traits are used everywhere in Rust, including the standard library.
π± Real-World: Environment Variables
Here's a real-world use case: reading env vars safely.
use std::env;
// Safe error handling
match env::var("REDIS_INTERNAL") {
Ok(val) => println!("{}", val),
Err(_) => println!("Environment variable not found"),
}
// When you're sure it's set (be cautious)
let redis_value = env::var("REDIS_INTERNAL").unwrap();
β what you learnt
β Generics allow for type-safe and reusable code
β Traits define capabilities for types
β
impl
blocks add methods to structsβ Generic structs = power + flexibility
β Trait bounds like
T: Add + Copy
enforce required behavior
π Resources
π Code examples:
github.com/ichiragkumar/rust-basics
π¦ Follow me for more:
https://x.com/imchiragkumar/
Subscribe to my newsletter
Read articles from CHIRAG KUMAR directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

CHIRAG KUMAR
CHIRAG KUMAR
Full stack Developer