我想抽象作用于不同职业ProfessionEnum
的枚举的代码,其中每个职业Student
、Teacher
等都是具有其自己的一组功能的特征.我希望对特征的实际实现进行分组.例如:
- A组:
StudentA
和TeacherA
使用数据库调用实现各自的特征 - B组:
StudentB
和TeacherB
使用API调用实现各自的特征
我希望TeacherA
能够返回StudentA
和ProfessionEnum
,其中所有变体都在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
型是一样的,但现在我意识到这并不能保证.我不太知道如何进一步限制这种类型.
你对如何重组代码以便我能达到预期的结果有什么建议吗?