Rust Learning Path — Chapter 13. Generics let you write one implementation that works with many concrete types while preserving Rust's static type safety.
Why generics?
Without generics, similar logic often gets duplicated for i32, f64, strings, and custom types. A generic type parameter acts as a placeholder for a concrete type chosen by the caller.
Generic functions
fn first<T>(items: &[T]) -> Option<&T> { items.first() } fn main() { let numbers = vec![10, 20, 30]; let names = vec!["api", "db"]; println!("{:?}", first(&numbers)); println!("{:?}", first(&names)); }Generic structs
#[derive(Debug)] struct Point<T> { x: T, y: T, } let integer = Point { x: 3, y: 7 }; let float = Point { x: 1.5, y: 2.5 };Multiple type parameters
struct Pair<T, U> { first: T, second: U, } let pair = Pair { first: "port", second: 8080, };Generic enums you already know
enum Option<T> { Some(T), None, } enum Result<T, E> { Ok(T), Err(E), }This is why Option, Option, Result, and many other combinations use the same abstractions.
Generic methods
impl<T> Point<T> { fn x(&self) -> &T { &self.x } }Why constraints are needed
A completely unconstrained T cannot automatically be compared, formatted, added, or cloned. Traits describe the behavior a generic type must provide. That leads directly to Chapter 14.
Monomorphization
Rust generally compiles generic code by producing concrete implementations for the types actually used. This is one reason generic abstractions can remain strongly typed without requiring a traditional runtime-generic dispatch mechanism for ordinary generic functions.
Mini lab: reusable API response
#[derive(Debug)] struct ApiResponse<T> { status: u16, data: T, } fn success<T>(data: T) -> ApiResponse<T> { ApiResponse { status: 200, data } } fn main() { let text = success(String::from("healthy")); let count = success(42_u64); println!("{text:?}"); println!("{count:?}"); }Common mistakes
- Assuming every T supports an operation such as + or println!("{}") .
- Adding generic parameters when concrete types would make an API clearer.
- Confusing generics with trait objects; they solve related but different problems.
Next: Chapter 14 — Traits and Trait Bounds.
Join the discussion
0 CommentsAsk questions, add context, or share what worked.
More from Melochip Editorial
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026Related articles
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026
Learn Kubernetes monitoring and logs with kubectl logs, events, metrics-server, top commands, Prometheus, Graf...
5 min read · Sep 17, 2026Stay in the loop. Get new Melochip articles
Receive Melochip article updates when new articles are available. Explicit opt-in only.
No comments yet. Start the discussion.