Generic Structs
In this page:
Defining a Generic Struct
A struct can be generic over one or more type parameters, letting the same struct definition hold different concrete types across different instances.
Example: Defining a Generic Struct
struct Wrapper<T> {
value: T,
}
fn main() {
let int_wrapper = Wrapper { value: 5 };
let str_wrapper = Wrapper { value: "text" };
println!("{} and {}", int_wrapper.value, str_wrapper.value);
}
Login to try C/C++/Java/PHP code in the editor
Generic Struct with Multiple Type Parameters
A struct can use more than one generic type parameter, allowing its fields to hold independent, potentially different concrete types.
Example: Generic Struct with Multiple Type Parameters
struct Pair<A, B> {
first: A,
second: B,
}
fn main() {
let pair = Pair { first: 1, second: "one" };
println!("{} - {}", pair.first, pair.second);
}
Login to try C/C++/Java/PHP code in the editor
Methods on a Generic Struct
An impl block for a generic struct repeats the type parameter, letting methods work with the struct's generic field regardless of which concrete type it holds.
Example: Methods on a Generic Struct
struct Wrapper<T> {
value: T,
}
impl<T> Wrapper<T> {
fn get(&self) -> &T {
&self.value
}
}
fn main() {
let w = Wrapper { value: 42 };
println!("{}", w.get());
}
Login to try C/C++/Java/PHP code in the editor
Adding Trait Bounds on Methods
Individual methods can add trait bounds beyond what the struct itself requires, restricting that specific method to types with the needed capability.
Example: Adding Trait Bounds on Methods
struct Pair<T> {
a: T,
b: T,
}
impl<T: PartialOrd + std::fmt::Display> Pair<T> {
fn larger(&self) -> &T {
if self.a > self.b { &self.a } else { &self.b }
}
}
fn main() {
let pair = Pair { a: 10, b: 20 };
println!("Larger: {}", pair.larger());
}
Login to try C/C++/Java/PHP code in the editor
- Forgetting to declare
<T>on the struct itself before usingTas a field's type. - Assuming a generic struct with one type parameter
<T>can hold two different types in two fields typedT-- both fields must match that same concrete type. - Not adding a trait bound when a method inside the
implblock needs to perform an operation only some types support.
- A generic struct declares its type parameter in angle brackets, e.g.
struct Wrapper<T> { value: T }. - All fields typed with the same generic parameter
Tmust hold the same concrete type within one instance. - Methods can add extra trait bounds beyond the struct's own declaration when they need specific capabilities.
- Generic structs let you avoid writing near-duplicate types for each concrete kind of data you want to store.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: