That being said, there are also cases where you know all types that implement a trait. That's when I usually recommend using an enum, if someone asks for performance optimization tips.
In that situation, you may also store each individual type in a separate collection or sort them by type in a single collection. Those are good ways to optimize for performance, but at a cost of added complexity. As always, do not optimize too early.
The trade-offs are as follows:
- Performance:
- Generics
- Enums
- Trait Objects
- Complexity (least first):
- Trait Objects
- Enums
- Generics
- Binary Size (smallest first):
- Trait Objects
- Enums
- Generics
- Flexibility:
- Generics
- Enums / Trait Objects¹
- Privacy:
- Trait Objects
- Enums
- Generics
¹) Enums allow calling generic methods, but require a fixed amount of types. Trait objects aren't limited to a fixed amount of implementing types, but can't call generic methods and are limited in other ways, as well. See: Object Safety