lazy-static.rs
lazy-static.rs copied to clipboard
Using dynamic dispatch with `lazy_static`
I'm not super experienced with dynamic dispatch, so there may be a better approach to solve this problem—feel free to point me in the right direction.
I want to have an enum translate to a lazy_static singleton. This is the classic example of something that wants to be const but requires allocation. However, I have two different types that I want the enum to translate to. To enable this, I wrapped the type in a Box<dyn Trait>. However, that doesn't appear to work with lazy_static.
Is there a way to resolve this situation? Here's an example of the kind of thing I'm trying to do:
lazy_static! {
static ref ENUM_A_BOX: Box<dyn Trait> = Box::new(StructA {});
static ref ENUM_B_BOX: Box<dyn Trait> = Box::new(StructB {});
static ref ENUM_C_BOX: Box<dyn Trait> = Box::new(StructC {});
}
enum Enum {
A,
B,
C,
}
impl Enum {
pub fn to_lazy_box(&self) -> Box<dyn Trait> {
match self {
Enum::A => *ENUM_A_BOX,
Enum::B => *ENUM_B_BOX,
Enum::C => *ENUM_C_BOX,
}
}
}
trait Trait {}
struct StructA {}
struct StructB {}
struct StructC {}
impl Trait for StructA {}
impl Trait for StructB {}
impl Trait for StructC {}
The error you are getting is because all statics created with lazy_static have to be Send and Sync. If you change Box<dyn Trait + Send + Sync>, it works. (I had to change another unrelated problem, but nevermind.)
Apart from that: do you need to return Box<_> from to_lazy_box? Are you sure? If not, you could just make the statics have the type Box<StructA> (and B and C) and return a &dyn Trait from to_lazy_box.
And I do understand you correctly that this is a question rather than a feature request, right?