< 返回版块

hjiayz 发表于 2019-10-28 10:23

Tags:关联类型,泛型

pub trait Foo<T>{}

pub trait Foo

    type T;

}

两种写法中 关联类型受到很多限制。 比如 T 如果存在生命周期,

是否泛型trait可以完全取代关联类型?

评论区

写评论
作者 hjiayz 2019-10-28 12:40

一个完整的例子

pub trait Foo<T=F>{
    fn foo();
}

pub struct F;

pub struct M<'a> {
    str:&'a str,
}

pub struct Z;

impl<'a> Foo<M<'a>> for Z {
    fn foo() {
        println!("foo M<'a> for Z")
    }
}

impl<'a> Foo for Z {
    fn foo() {
        println!("foo F for Z")
    }
}

impl Foo for F {
    fn foo() {
        println!("foo for F")
    }
}

fn main(){
    <Z as Foo>::foo();
    <Z as Foo<M>>::foo();
    F::foo()
}
作者 hjiayz 2019-10-28 12:27

对以下内容的回复:

可以这样

pub trait Foo<T=String>{}

参照https://doc.rust-lang.org/std/ops/trait.Add.html

liyiheng 2019-10-28 11:53

区别在于当如示例 19-21 那样使用泛型时,则不得不在每一个实现中标注类型。这是因为我们也可以实现为 Iterator for Counter,或任何其他类型,这样就可以有多个 Counter 的 Iterator 的实现。换句话说,当 trait 有泛型参数时,可以多次实现这个 trait,每次需改变泛型参数的具体类型。接着当使用 Counter 的 next 方法时,必须提供类型注解来表明希望使用 Iterator 的哪一个实现。 通过关联类型,则无需标注类型因为不能多次实现这个 trait。对于示例 19-20 使用关联类型的定义,我们只能选择一次 Item 会是什么类型,因为只能有一个 impl Iterator for Counter。当调用 Counter 的 next 时不必每次指定我们需要 u32 值的迭代器。

1 共 3 条评论, 1 页