Rust EnumsFunctionsGenericsRustStructs

Article & Tutorial

Rust Generics: Generic Functions, Structs, Enums and Methods Explained

Learn Rust generics with generic functions, structs, enums, methods, type parameters, multiple generic types and monomorphization examples.

Rust Generics: Generic Functions, Structs, Enums and Methods Explained abstract technical illustration
Rust Generics: Generic Functions, Structs, Enums and Methods Explained abstract technical illustration
Contents

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

bash
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

bash
#[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

bash
struct Pair<T, U> { first: T, second: U, } let pair = Pair { first: "port", second: 8080, };

Generic enums you already know

bash
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

bash
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

bash
#[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.

Did this help?

Yes No

Join the discussion

0 Comments

Ask questions, add context, or share what worked.

Sign in to join the discussion

No comments yet. Start the discussion.

More from Melochip Editorial

Related articles

Stay in the loop. Get new Melochip articles

Receive Melochip article updates when new articles are available. Explicit opt-in only.

No pre-checked boxes. Unsubscribe support is part of the subscriber foundation.