强制特定结构实现特征组合

时间:2021-02-28 15:18:19

标签: rust traits

我正在尝试定义两个可以在以后通过多种方式实现的特征。 第一个是 trait A,第二个是 trait B,它基本上是一个实现 trait A 的元素向量。

trait A {
    fn name(&self) -> &str;
}

trait B {
    fn len(&self) -> usize;
    fn add<T: A>(&mut self, item: T) -> bool;
}

#[derive(PartialEq)]
struct ImplA {
    name: String,
}

impl A for ImplA {
    fn name(&self) -> &str {
        &self.name
    }
}

struct ImplB {
    items: Vec<ImplA>,
}

impl B for ImplB {
    fn len(&self) -> usize {
        self.items.len()
    }

    fn add(&mut self, item: ImplA) -> bool {
        if !self.items.contains(&item) {
            self.items.push(item);
            true
        } else {
            false
        }
    }
}

add 函数的代码强制项实现类型 A。 然后我定义了两个结构体 ImplA 来实现 trait A 没有问题 然后结构 ImplB 应该实现 trait B 但只接受 输入 ImplA

我为 add 函数的签名尝试了几种组合,但没有成功编译。

原来的错误是

error[E0308]: mismatched types
  --> src/main.rs:32:33
   |
31 |     fn add<T: A>(&mut self, item: T) -> bool {
   |            ----- this type parameter
32 |         if !self.items.contains(&item) {
   |                                 ^^^^^ expected struct `ImplA`, found type parameter `ImplA`
   |
   = note: expected reference `&ImplA` (struct `ImplA`)
              found reference `&T` (type parameter `T`)

我想我明白,但提到的解决方案并没有解决我的问题,因为它意味着 ImplB 可以接受任何实现 A 的结构,这不是我想要的。

1 个答案:

答案 0 :(得分:2)

您遇到的一个问题是 add() 的类型参数在每次调用时都允许 A 的不同实现,但在其他地方您依赖它总是相同的类型对于 B 的给定实现。

在 Rust 中,可以使用 B trait 上的关联类型来表达此约束:

trait B {
    type Item: A;
    fn len(&self) -> usize;
    fn add(&mut self, item: Self::Item) -> bool;
}

然后,当您实现 B 时,您为该实现提供了 A 的固定类型:

impl B for ImplB {
    type Item = ImplA;
    
    fn len(&self) -> usize {
        self.items.len()
    }

    fn add(&mut self, item: ImplA) -> bool {
        if !self.items.contains(&item) {
            self.items.push(item);
            true
        } else {
            false
        }
    }
}
相关问题