2015-07-06 66 views
4

我试图在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) {} 

我期望上面的代码可以编译,但它不会。

相反,我得到:

error: the trait `Person` is not implemented for the type `<<C as Catalog>::Dir as Directory<<C as Catalog>::Per>>::Per` [E0277] 

其中,AFAICT,意味着编译器不能确定该人变量的人物特质。

我使用以下rustc版本:

rustc 1.2.0-dev (a19ed8ad1 2015-06-18) 

我缺少的东西?

回答

5

这里有修正:在Directory

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

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

4

下面是正确的代码:

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) {} 

<P: Person>是泛型的语法。关联的类型定义不使用通用语法。

去寻找一般的全名;不要简写它Per,离开它Person。它始终是合格的(Directory::Person,C::Person,& c。),所以没有歧义。 (DirDirectory公认的缩写形式,所以我想要么是可以接受的。我可能会倾向于去Directory,但是。)

有没有必要对Catalog指定相关类型Person,无论是; Self::Dir::Person会做。