将所有变体实现相同特征的枚举转换为Rust中的框? [英] Converting an enum where all variants implement the same trait to a box in Rust?

查看:83
本文介绍了将所有变体实现相同特征的枚举转换为Rust中的框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特征 Foo ,有一些实现,还有一个枚举 Foos ,每个实现都有一个变体。我希望能够将我的枚举转换为 Box< dyn Foo>

I have a trait Foo, with some implementations, together with an enum Foos with one variant per implemention. I want to be able to convert my enum into Box<dyn Foo>.

这是我当前的解决方案:

This is my current solution:

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 中有很多样板。随着变体数量的增加,功能也会随之增加。有没有更简单的方法可以做到这一点?

It works, but there's a lot of boiler plate in into_enum. As the number of variants grow, so will the function. Is there a simpler way to do this? It feels like it should be a one liner!

推荐答案

使用 enum_dispatch 板条箱,您可以编写

With the enum_dispatch crate, you can write

#[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

to get a generated impl Foo for Foos. You can then convert Foos to Box<dyn Foo> with simply Box::new.

此方法有潜在的缺点: Box :: new(Foos :: A(FooA)) 包含 Foos ,而不是 FooA ,因此这将导致这两个从 dyn Foo Foos 的动态调度和 enum 调度从 Foos FooA

There is a potential downside to this approach: Box::new(Foos::A(FooA)) contains a Foos, not an FooA, so it will incur the overhead of both the dynamic dispatch from dyn Foo to Foos and the enum dispatch from Foos to FooA.

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

On the other hand, now that you have impl Foo for Foos: everywhere you would have used Box<dyn Foo>, you’ll instead be able to directly use Foos, which should be more efficient in every way.

这篇关于将所有变体实现相同特征的枚举转换为Rust中的框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆