【问题标题】:How to instantiate the same struct with different implementations of a trait?如何用不同的特征实现实例化相同的结构?
【发布时间】:2021-01-05 21:59:06
【问题描述】:

我有一个特征,它由同一个结构以不同的方式实现。为了做到这一点,我有不同的结构,它们有不同的实现。为了抽象,我将把这些结构称为 A-Z:

trait Trait {
    fn bar<T: Trait> (&self, z: &Struct3<T>) -> Struct3<T>;
}
struct StructA {
    name: String,
    color: String,
}
impl Trait for StructA {
    fn bar<T: Trait> (&self, z: &Struct3<T>) -> Struct3<T>{

        let mut list = Vec::new();
        list.push(self.clone());

        let y = Struct2::<T> {
            name: z.y.name,
            list: list,
        };

        Struct3::<T> {
            point: 1,
            y: y,
        }
    }
}
struct StructZ {
    name: String,
    color: String,
}
impl Trait for StructZ {
    fn bar<T: Trait> (&self, z: &Struct3<T>) -> Struct3<T>{

        let mut list = Vec::new();
        list.push(self.clone());

        let y = Struct2::<T> {
            name: z.y.name,
            list: list,
        };

        Struct3::<T> {
            point: 26,
            y: y,
        }
    }
}

是否有另一种方法来解决这个问题,以便结构的每个实例都有不同的 trait 实现,或者制作一个新结构是最好的方法?

我是编译语言的新手。我所做的大部分工作都是使用 Python 和 TypeScript。

【问题讨论】:

  • 唯一的区别是point 值吗?还是比这更复杂?你会如何在 Python 或 Typescript 中做到这一点?
  • 比这个例子复杂。我简化了以便更容易询问。在 python 或 OO 语言中,我会将 trait 设为接口并使用基类实现它。然后,我将使用 A...Z 类扩展该基类
  • @WhyNot 我认为您在面向对象的模式上过于努力了 x) Rust 没有继承的概念,因此问题的解决方法通常完全不同。我建议你明确你的意图。
  • 好的,那我会想办法更​​好的重构它。在大学里,我在 OO 原则上受到了很大的压力,但我一直在努力改掉这个习惯。谢谢!

标签: struct rust traits


【解决方案1】:

做到这一点的一种方法是使您的 trait 在某些类型上通用(即使该类型实际上并未在 trait 内部使用)。

trait Trait<T> { /* ... */ }

这使您可以为同一个结构多次实现它。

impl Trait<bool> for Struct { /* ... */ }
impl Trait<u32> for Struct { /* ... */ }

这里,boolu32 只是成为编译时标志来选择您要使用的 Trait 的实现。

let struct_3a = Trait::<bool>::bar(&my_object, /* ... */);
let struct_3b = Trait::<u32>::bar(&my_object, /* ... */);

我在这里使用了boolu32,但您可以在这里使用自己的类型以使一切更清晰。

【讨论】:

  • 这是一个非常好的主意,我可能会在某个时候使用它!不幸的是,结构 A...Z 的实际数量将是数千个,所以我认为这不适用于这个实现。不过,这是一个非常有趣的 hack。
  • 你可以使用像struct VariantA;这样的空结构,而不是像bool这样的原始类型作为通用特征;这可能会使其更清晰,并消除对可扩展性的担忧。
  • 同意@DanR。您还可以通过将 impl 与包含不同类型的枚举挂钩来使事情变得更容易。
猜你喜欢
  • 1970-01-01
  • 2019-01-28
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
相关资源
最近更新 更多