Course contentsShow
← Rust
Lesson 675 of 1,9106. Generics and Static DispatchFree lesson

Generic Struct Definitions

Create flexible data containers that handle diverse data types without duplicating memory layout logic.

In this lesson, you will learn how to define flexible data containers that handle diverse data types without needing to duplicate your memory layout logic.

Why Generics Matter

Up until now, if you wanted a struct to hold a value, you had to commit to a specific type, like i32 or String. If you later needed to store a f64 or a custom struct, you would have to define an entirely new type. This leads to code bloat and maintainability headaches. Generic Struct Definitions solve this by letting you define the "shape" of a container while leaving the specific "content type" to be decided later.

Defining a Generic Container

You introduce a type parameter using angle brackets <T> immediately after the struct name. Think of T as a placeholder variable for a type.

struct Container<T> {
    value: T,
}

By defining Container<T>, you are telling the Rust compiler: "I am creating a blueprint for a struct, and the type of value will be determined whenever this struct is instantiated."

How It Works in Practice

When you use this struct, you "bind" the type parameter to a concrete type:

let int_box = Container { value: 42 };         // T becomes i32
let string_box = Container { value: "Rust" };  // T becomes &str

Because of monomorphization (which you learned previously), the compiler generates a unique version of Container for every type you pass in. This means there is no performance penalty for this flexibility; the resulting machine code is just as efficient as if you had written a specific struct for each type manually.

By using generic definitions, you separate the structure of your data from the identity of the data it holds. This allows you to build powerful, reusable components that adapt to the needs of your system without sacrificing type safety or execution speed.

Key Takeaway: Generic structs use type parameters like <T> to define flexible data layouts that the compiler automatically specializes for you at compile time.