When one already knows all the finite number of types involved in some code which needs dynamic polymorphism, using enum can be better for performances compared to using Box since the latter uses dynamic memory allocation and you'll need to use trait objects which have virtual function call as well.
That said, compared to the equivalent code in C++ using std::variant and std::visit, looks like Rust in this scenario has more boilerplate coding involved, at least for me (I have not yet learned to use procedural macros). Making some example here: I have a bunch of struct types:
struct A {
// ...
}
struct B {
// ...
}
// ...
struct Z {
// ...
}
They all implement the trait AlphabetLetter which is:
trait AlphabetLetter {
fn some_function(&self);
}
Since the set of types involved is known and limited, I want to use enum:
enum Letter {
AVariant(A),
BVariant(B),
// ...
ZVariant(Z),
}
Already here we have the first boilerplate: I need to add a name for the enum value for every type variant involved. But the real issue is: enum Letter is itself an AlphabetLetter, it just represent the fact that we do not know at runtime which letter it is. So I started implementing the trait for it:
impl AlphabetLetter for Letter {
fn some_function(&self) {
match self {
Letter::AVariant(letter) => letter.some_function();
Letter::BVariant(letter) => letter.some_function();
// ...
Letter::ZVariant(letter) => letter.some_function();
}
}
}
And yes, this can become easily a lot of code, but I found no other way of doing it. In C++, thanks to generic lambdas, one can just std::visit a std::variant and it's a one liner. How can I do the same without manually writing all the pattern matching for every function in the traits X every variant in the enum?
std::visitfunctionally similar to using Rust macros (note that C macros are another thing entirely). The price you pay for this convenience in C++ is that type errors are reported at use rather than declaration, and the errors for doing something incompatible inside the lambda can be... opaque.matchstatement does (and possibly faster).