我有一个特征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。然后,您可以仅使用FoosBox<dyn Foo>转换为Box::new

这种方法有一个潜在的缺点:Box::new(Foos::A(FooA))包含Foos而不是FooA,因此它将招致从dyn FooFoos的动态分派(dispatch)以及从enumFoosFooA分派(dispatch)的开销。

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

关于enums - 将所有变体实现相同特征的枚举转换为Rust中的框?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54056660/

10-12 18:08