繁体   English   中英

将所有变体实现相同特征的枚举转换为Rust中的框?

[英]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::newFoos转换为Box<dyn Foo>

这种方法有一个潜在的缺点: Box::new(Foos::A(FooA))包含一个Foos ,而不是一个FooA ,因此它将FooAdyn FooFoos的动态分派和enum分派的开销。从FoosFooA

另一方面,现在您已经impl Foo for Foos :在使用Box<dyn Foo> ,您都可以直接使用Foos ,这在每种方式上都应该更有效率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM