关联类型 associated types
不使用关联类型,使用泛型的情形:
struct Container(i32, i32);
trait Contains<A, B> {
fn contains(&self, _: &A, _: &B) -> bool;
fn first(&self) -> i32;
fn last(&self) -> i32;
}
impl Contains<i32, i32> for Container {
fn contains(&self, number_1: &i32, number_2: &i32)
-> bool {
(&self.0 == number_1) && (&self.1 == number_2)
}
fn first(&self) -> i32 { self.0 }
fn last(&self) -> i32 { self.1 }
}
fn difference<A, B, C>(container: &C) -> i32 where
C: Contains<A, B> {
container.last() - container.first()
}
不使用关联类型的话,difference
函数的类型定义会很繁琐。
使用关联类型的情形:
struct Container(i32, i32);
trait Contains {
type A;
type B;
fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
fn first(&self) -> i32;
fn last(&self) -> i32;
}
impl Contains for Container {
type A = i32;
type B = i32;
fn contains(&self, number_1: &i32, number_2: &i32)
-> bool {
(&self.0 == number_1) && (&self.1 == number_2)
}
fn first(&self) -> i32 { self.0 }
fn last(&self) -> i32 { self.1 }
}
fn difference<C: Contains>(container: &C) -> i32 {
container.last() - container.first()
}
最佳实践为:如果对于特定的类型,只期望有一个特征的实现,那么使用关联类型,否则使用泛型类型。或者说,在能使用关联类型的地方,尽量都使用关联类型。
如何理解上面的话呢:对于每个要实现特征 Contains 的结构体 Container 来说,如果只需要一个特征的实现,那么使用关联类型。如果在一个结构体中,就需要对特征进行多个不同类型参数的实现,比如要在 Container 中同时实现 i32 类型与 u32 类型的 contains 方法,那么就使用泛型。