特征和相关类型

yni*_*ous 4 traits rust associated-types

我正在尝试使用特征和相关类型在Rust上实现一些东西.我不确定如何用文字形成我的问题,所以我将添加一个代码片段,希望能说明我正在尝试做什么.

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) {}
Run Code Online (Sandbox Code Playgroud)

我希望上面的代码可以编译,但事实并非如此.

相反,我得到:

error: the trait `Person` is not implemented for the type `<<C as Catalog>::Dir as Directory<<C as Catalog>::Per>>::Per` [E0277]
Run Code Online (Sandbox Code Playgroud)

其中,AFAICT意味着编译器无法确定person变量具有Person特征.

我正在使用以下rustc版本:

rustc 1.2.0-dev (a19ed8ad1 2015-06-18)
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

eul*_*isk 5

这里有更正:

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

型的PerDirectory可在性状实现中可以重新定义.编译器不知道Self::Per(实现中是否重新定义Per)是否实现了特征Person,因此必须将其绑定以实现Person.