我想抽象作用于不同职业ProfessionEnum的枚举的代码,其中每个职业StudentTeacher等都是具有其自己的一组功能的特征.我希望对特征的实际实现进行分组.例如:

  • A组:StudentATeacherA使用数据库调用实现各自的特征
  • B组:StudentBTeacherB使用API调用实现各自的特征

我希望TeacherA能够返回StudentAProfessionEnum,其中所有变体都在A组中,但不能在B组中.

我也不想用任何dyn.我一开始试着用impl实现这一功能,但对它的语言支持还没有准备好.因此,我try for each 职业创建一个具有关联类型的特征Profession,然后实现一个ProfessionA,其中所有关联类型都属于A组.以下是我的try :

pub trait Profession {
    type T: Teacher;
    type S: Student;
}

pub trait Student {
    type P: Profession;
}

pub trait Teacher {
    type P: Profession;

    fn get_student(&self) -> <Self::P as Profession>::S;
}

pub enum ProfessionEnum<P>
where
    P: Profession,
{
    Student(P::S),
    Teacher(P::T),
}

// Concrete implementation of Profession, could be many
pub struct ProfessionA {}

impl Profession for ProfessionA {
    type T = TeacherA;
    type S = StudentA;
}

pub struct TeacherA {}

impl Teacher for TeacherA {
    type P = ProfessionA;

    fn get_student(&self) -> <Self::P as Profession>::S {
        StudentA {}
    }
}

pub struct StudentA {}

impl Student for StudentA {
    type P = ProfessionA;
}

// function generic over implementations of Profession
pub fn get_students<P: Profession>(p: ProfessionEnum<P>) {
    let mut students: Vec<P::S> = vec![];

    match p {
        ProfessionEnum::Student(s) => students.push(s),
        ProfessionEnum::Teacher(t) => students.push(t.get_student()), // ERROR
    }
}

fn main() {
    let p = ProfessionEnum::<ProfessionA>::Teacher(TeacherA {});
    get_students(p);
}

我得到以下错误:

error[E0308]: mismatched types
  --> src/main.rs:54:55
   |
49 | pub fn get_students<P: Profession>(p: ProfessionEnum<P>) {
   |                     - this type parameter
...
54 |         ProfessionEnum::Teacher(t) => symbol_buf.push(t.get_student()),
   |                                                  ---- ^^^^^^^^^^^^^^^ expected type parameter `P`, found associated type
   |                                                  |
   |                                                  arguments to this function are incorrect
   |
   = note: expected associated type `<P as Profession>::S`
              found associated type `<<<P as Profession>::T as Teacher>::P as Profession>::S`
   = note: you might be missing a type parameter or trait bound
note: associated function defined here

一开始我对此感到惊讶,因为我以为<<<P as Profession>::T as Teacher>::P as Profession>::S型和<P as Profession>::S型是一样的,但现在我意识到这并不能保证.我不太知道如何进一步限制这种类型.

你对如何重组代码以便我能达到预期的结果有什么建议吗?

Link to playground

推荐答案

这很简单:

pub trait Profession {
    type T: Teacher<P = Self>;
    type S: Student<P = Self>;
}

Rust相关问答推荐

Tauri tauri—apps/plugin—store + zustand

如何从Rust记录WASM堆内存使用情况?

正则表达式中的重叠匹配?(铁 rust 正则式发动机)

是否可以在不切换到下一个位置的情况下获得迭代器值:

在Rust中判断编译时是否无法访问

完全匹配包含大小写的整数范围(&Q;)

无法实现整型类型的泛型FN

在Rust中克隆源自INTO_ITER()的迭代器的成本?

在铁 rust 中,如何一次只引用几件事中的一件?

Tokio';s io::用Cursor拆分<;Vec<;u8>>;赢得';t get the full writted data

用于实现获取 struct 体 id 的特征规范

如何使用tracing-subscriberRust crate 构建多编写者、全局过滤订阅者

Rust LinkedList 中的borrow 判断器错误的原因是什么?

.to_owned()、.clone() 和取消引用 (*) 之间有区别吗?

为什么 Rust 的临时值有时有参考性有时没有?

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

如何使用 rust bindgen 生成的 std_vector

在 Rust 中为泛型 struct 编写一次特征绑定

将文件的第一行分别读取到文件的其余部分的最有效方法是什么?

以下打印数组每个元素的 Rust 代码有什么问题?