【问题标题】:Is it possible to upcast to a trait when destructuring enums?解构枚举时是否可以向上转换为特征?
【发布时间】:2018-05-08 16:19:56
【问题描述】:

我希望能够将枚举变体解构/向上转换为常用实现的特征。这是设置:

trait SomeTrait {
    fn some_func(&self);
}

struct SomeStruct1;
impl SomeTrait for SomeStruct1 {
    fn some_func(&self) {}
}

struct SomeStruct2;
impl SomeTrait for SomeStruct2 {
    fn some_func(&self) {}
}

enum SomeEnum {
    Value1(SomeStruct1),
    Value2(SomeStruct2),
}

这是我尝试过的一种可能性:

fn call_some_func(some_enum: SomeEnum) {
    match some_enum {
        SomeEnum::Value1(ref some_trait: &SomeTrait) |
        SomeEnum::Value2(ref some_trait: &SomeTrait) => some_trait.some_func()
    }
}

导致了这个错误:

error: expected one of `)`, `,`, or `@`, found `:`
  --> src/main.rs:22:40
   |
22 |         SomeEnum::Value1(ref some_trait: &SomeTrait) |
   |                                        ^ expected one of `)`, `,`, or `@` here

这是我的另一个想法:

fn call_some_func2(some_enum: SomeEnum) {
    match some_enum {
        _(ref some_trait: &SomeTrait) => some_trait.some_func()
    }
}

也失败了:

error: expected one of `=>`, `if`, or `|`, found `(`
  --> src/main.rs:22:10
   |
22 |         _(ref some_trait: &SomeTrait) => some_trait.some_func()
   |          ^ expected one of `=>`, `if`, or `|` her

有人知道完成这种解构的方法吗?

【问题讨论】:

  • 枚举的每个案例是否都包含实现该特征的内容,就像您在此处显示的那样,还是有些案例不包含?
  • 对于我目前的用法,是的,它们都实现了该特征。我不会反对允许模式匹配的解决方案,因此这不是必需的。

标签: enums rust traits upcasting


【解决方案1】:

不,你不能同时解构。您可以在 之后这样做:

// My preferred
fn call_some_func(some_enum: SomeEnum) {
    let x: &SomeTrait = match some_enum {
        SomeEnum::Value1(ref x) => x,
        SomeEnum::Value2(ref x) => x,
    };
    x.some_func();
}
// Also works
fn call_some_func(some_enum: SomeEnum) {
    let x = match some_enum {
        SomeEnum::Value1(ref x) => x as &SomeTrait,
        SomeEnum::Value2(ref x) => x,
    };
    x.some_func();
}

我鼓励您将其提取到一种方法中以供重用:

impl SomeEnum {
    fn as_trait(&self) -> &SomeTrait {
        match *self {
            SomeEnum::Value1(ref x) => x,
            SomeEnum::Value2(ref x) => x,
        }
    }
}

fn call_some_func(some_enum: SomeEnum) {
    some_enum.as_trait().some_func();
}

如果所有变体都实现了它,则可能会在枚举本身上实现该特征。这样,消费者就不必关心:

impl SomeTrait for SomeEnum {
    fn some_func(&self) {
        self.as_trait().some_func()
    }
}

【讨论】:

  • 谢谢。感觉就像不幸的样板,但很好地封装了它。
猜你喜欢
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 2015-07-12
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
相关资源
最近更新 更多