Rust 性状和相关类型

Rust 性状和相关类型,rust,traits,associated-types,Rust,Traits,Associated Types,我正在尝试用特性和相关类型来实现一些关于生锈的东西。我不知道如何用文字来表达我的问题,所以我将添加一个代码片段,希望能说明我正在尝试做什么 pub trait Person {} pub trait Directory<P: Person> { type Per = P; fn get_person(&self) -> Self::Per; } pub trait Catalog { type Per : Person; type D

我正在尝试用特性和相关类型来实现一些关于生锈的东西。我不知道如何用文字来表达我的问题,所以我将添加一个代码片段,希望能说明我正在尝试做什么

pub trait Person {}

pub trait Directory<P: Person> {
    type Per = P;
    fn get_person(&self) -> Self::Per;
}

pub trait Catalog {
    type Per : Person;
    type Dir : Directory<Self::Per>;

    fn get_directory(&self) -> Self::Dir;
}

fn do_something<C>(catalog: C) where C: Catalog {
    let directory : C::Dir = catalog.get_directory();

    // let person : C::Per = directory.get_person();
    // The code above fails with:
    //  error: mismatched types:
    //   expected `<C as Catalog>::Per`,
    //      found `<<C as Catalog>::Dir as Directory<<C as Catalog>::Per>>::Per`
    //   (expected trait `Catalog`,
    //       found trait `Directory`) [E0308]

    let person = directory.get_person();
    do_something_with_person(person);
}

fn do_something_with_person<P: Person>(p: P) {}

我遗漏了什么吗?

这里是更正:

pub trait Directory<P: Person> {
    type Per : Person = P;
    fn get_person(&self) -> Self::Per;
}
pub目录{
人均类型:人=P;
fn get_person(&self)->self::Per;
}

可以在trait实现中重新定义
目录
中的类型
Per
。编译器不知道
Self::Per
(这是实现中重新定义的
Per
)是否实现了trait
Person
,因此您必须将其绑定到实现
Person

以下是正确的代码:

pub trait Person {}

pub trait Directory {
    type Person: Person;
    fn get_person(&self) -> Self::Person;
}

pub trait Catalog {
    type Dir: Directory;

    fn get_directory(&self) -> Self::Dir;
}

fn do_something<C: Catalog>(catalog: C) {
    let directory = catalog.get_directory();
    let person = directory.get_person();
    do_something_with_person(person);
}

fn do_something_with_person<P: Person>(p: P) {}
pub trait Person{}
发布特征目录{
类型人:人;
fn get_person(&self)->self::person;
}
发布特征目录{
类型Dir:目录;
fn get_目录(&self)->self::Dir;
}
fn do_something(目录:C){
let directory=catalog.get_directory();
让person=directory.get_person();
和某人做某事;
}
fn与某人做某事(p:p){}
是泛型语法。关联的类型定义不使用泛型语法

一般来说,取全名;不要将其缩写为Per,将其保留为Person。它总是限定的(
Directory::Person
C::Person
,&C),因此没有歧义。(
Dir
是公认的
Directory
的缩写形式,因此我想两者都可以接受。不过,我可能倾向于使用
Directory

也不需要在
目录
中指定关联的类型
人员
<代码>Self::Dir::Person就可以了

pub trait Directory<P: Person> {
    type Per : Person = P;
    fn get_person(&self) -> Self::Per;
}
pub trait Person {}

pub trait Directory {
    type Person: Person;
    fn get_person(&self) -> Self::Person;
}

pub trait Catalog {
    type Dir: Directory;

    fn get_directory(&self) -> Self::Dir;
}

fn do_something<C: Catalog>(catalog: C) {
    let directory = catalog.get_directory();
    let person = directory.get_person();
    do_something_with_person(person);
}

fn do_something_with_person<P: Person>(p: P) {}