Suppose we have a struct
that can contain a data member that has various types—a String
, a usize
, a boolean. This struct
can be implemented in Rust with a generic struct
.
With a type parameter, we can use an identifier like T to mean any type. The type is specified elsewhere in the program, not directly in the struct
definition itself.
This Rust program has a generic struct
called Item, and we specify it is a generic struct
by using angle brackets with a type identifier. The T means "the type specified by the caller."
struct
here with a single type argument T. We don't specify what the T might refer to.struct
contains one member field called data, with type T. So this could be a String
or usize
depending on how the struct
is created.impl
block adds methods to a struct
. Here we use the same T type that the Item uses, and we also require the Display trait.struct
twice, first with a String
"cat" and then with a usize
of value 10.// Part 1: specify a generic struct with one type argument. struct Item<T> { // Part 2: use the type argument name for a member of the struct. data: T, } // Part 3: add an impl block for the struct that requires the Display trait. impl<T: std::fmt::Display> Item<T> { pub fn print(&self) { println!("{}", self.data); } } fn main() { // Part 4: create the generic struct with String, and then usize types. let item = Item { data: String::from("cat"), }; item.print(); let number = Item { data: 10usize }; number.print(); }cat 10
With generic type parameters on a struct
, and an impl
block, we can have usable generics in Rust. In an impl
block, we can require a trait for the generic type like the Display trait.