首页 > 解决方案 > 如何为不同的特征集实现相同的方法?

问题描述

假设我有一个看起来像这样的通用结构:

struct MyStruct<T> {
    value: T
}

我想做 A Thing (TM),但它只有在某些 trait 实现中才有可能。所以我有:

impl<T: Trait1> MyStruct<T> {
    pub fn do_thing(&self) {
        // do something
    }
}

但不是每个T工具Trait1,所以我也想覆盖Trait2等作为备用选项。

impl<T: Trait2> MyStruct<T> {
    pub fn do_thing(&self) {
        // do the same thing in a different way
    }
}

这个解决方案不起作用,因为我do_thing()对任何T同时实现Trait1and的定义都有重复的定义Trait2,并且没有办法知道默认使用哪个。

那么,有什么方法可以指定回退顺序来告诉编译器do_thing()使用哪个实现?或者我应该从一个完全不同的角度来解决这个问题?

标签: data-structuresrusttraitsimplementation

解决方案


在稳定的生锈中没有办法做到这一点。Nightly专业化功能可能会对您有所帮助,如果您可以对另一个进行T更严格的定义(例如T: Trait1 + Trait2,对于高优先级实现和T: Trait1默认实现)。

编辑:我玩了一点,specialization似乎即使使用它也无法实现你想要的。

如果你想坚持稳定,你可能需要有不同的方法。仅当此结构的使用者确定它使用哪种类型 T 时才有可能,但如果是您的情况,这是最好的选择。

impl<T: Trait1> MyStruct<T> {
  pub fn do_thing(&self) {}
}

impl<T: Trait2> MyStruct<T> {
  pub fn do_another_thing(&self) {}
}

我想说为不同类型实现不同功能逻辑的最生锈的方法是使用enums而不是泛型。

struct MyStruct {
  value: MyEnum,
}

enum MyEnum {
  SimpleThing{...},
  MoreComplicatedThing{...},
}

impl MyStruct {
  do_thing(&self) {
    match self.value {
      MyEnum::SimpelThing{..} => self.do_simple_thing(),
      MyEnum::MoreComplicatedThing{..} => self.do_more_complicated_thing(),
    }
  }
}

推荐阅读