我有一个特征Foo
,它带有一些实现,以及一个枚举Foos
,每个实现都有一个变体。我希望能够将我的枚举转换为Box<dyn Foo>
。
这是我目前的解决方案:
trait Foo {}
struct FooA {}
impl Foo for FooA {}
struct FooB {}
impl Foo for FooB {}
struct FooC {}
impl Foo for FooC {}
enum Foos {
A(FooA),
B(FooB),
C(FooC),
}
impl Foos {
fn into_box(self) -> Box<dyn Foo> {
match self {
Foos::A(foo) => Box::new(foo),
Foos::B(foo) => Box::new(foo),
Foos::C(foo) => Box::new(foo),
}
}
}
它可以工作,但是
into_enum
中有很多样板。随着变体数量的增加,功能也会随之增加。有没有更简单的方法可以做到这一点?感觉应该是一根衬板! 最佳答案
使用 enum_dispatch
crate,您可以编写
#[macro_use]
extern crate enum_dispatch;
#[enum_dispatch]
trait Foo {}
struct FooA {}
impl Foo for FooA {}
struct FooB {}
impl Foo for FooB {}
struct FooC {}
impl Foo for FooC {}
#[enum_dispatch(Foo)]
enum Foos {
A(FooA),
B(FooB),
C(FooC),
}
获得生成的
impl Foo for Foos
。然后,您可以仅使用Foos
将Box<dyn Foo>
转换为Box::new
。这种方法有一个潜在的缺点:
Box::new(Foos::A(FooA))
包含Foos
而不是FooA
,因此它将招致从dyn Foo
到Foos
的动态分派(dispatch)以及从enum
到Foos
的FooA
分派(dispatch)的开销。另一方面,现在您有了
impl Foo for Foos
:到处都可以使用Box<dyn Foo>
,您将可以直接使用Foos
,这在每种方式上都应该更有效率。关于enums - 将所有变体实现相同特征的枚举转换为Rust中的框?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54056660/