[英]Converting an enum where all variants implement the same trait to a box in Rust?
我有一个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
有很多into_enum
。 随着变体数量的增加,功能也会随之增加。 有没有更简单的方法可以做到这一点? 感觉应该是一根衬板!
我最近想要类似的东西。 我无法为您提供单线,而是一个宏,该宏会自动生成相应的match
臂以及enum
变量:
macro_rules! impl_foos{($($enumvariant: ident($foo: ty),)*) => {
enum Foos {
$($enumvariant($foo),)*
}
impl Foos {
fn into_enum(self) -> Box<dyn Foo> {
match self {
$(Foos::$enumvariant(foo) => Box::new(foo),)*
}
}
}
}}
impl_foos!(
A(FooA),
B(FooB),
C(FooC),
);
这样,只有一个地方可以保留所有可能性,而其他所有东西都将生成。 也许甚至箱子enum_dispatch也有帮助。
into_enum(self)->Box<dyn Foo>
:它真的应该是into_enum(self)->Box<dyn Foo>
吗? 它不应该像as_foo(&self)->&dyn Foo
吗?
使用enum_dispatch
板条箱 ,您可以编写
#[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
生成生成的impl Foo for Foos
。 然后,您可以使用Box::new
将Foos
转换为Box<dyn Foo>
。
这种方法有一个潜在的缺点: Box::new(Foos::A(FooA))
包含一个Foos
,而不是一个FooA
,因此它将FooA
从dyn Foo
到Foos
的动态分派和enum
分派的开销。从Foos
到FooA
。
另一方面,现在您已经impl Foo for Foos
:在使用Box<dyn Foo>
,您都可以直接使用Foos
,这在每种方式上都应该更有效率。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.