Heterogeneous Collections with Enums
Enums give us a way to create collections that can store different types of element at runtime:
struct Dog {
name: String,
}
struct Cat {
age: u8,
}
struct Bird {
wingspan: f32,
}
enum AnyPet {
Dog(Dog),
Cat(Cat),
Bird(Bird),
}
fn main() {
let pets = vec![
AnyPet::Dog(Dog { name: "Fido".into() }),
AnyPet::Cat(Cat { age: 19 }),
AnyPet::Bird(Bird { wingspan: 12.3 }),
];
}
-
A common situation where we might need dynamic polymorphism is when we want to store different types of value in the same collection.
-
In the above example, we want to store both
Cats andDogs in the same list.Vecdoesn’t support this directly: All elements of theVecmust be the same type. -
Wrapping our two different pet types into a single
AnyPetenum gives us a unified type representation that can be stored in aVec, while allowing individual elements of theVecto be different types. -
This requires that we know all possible pet types up front, as we need to explicitly list them as different variants of the
AnyPetenum. This works well for libraries or applications that define the full set of possible types, but does not allow downstream users to extend our list of pet types. -
Later we will see that we can do the same thing with
dyn, which allows downstream extension at the cost of being harder to downcast and requiring dynamic dispatch.