关联类型
关联类型时在特征定义的语句块中,申明一个自定义类型,这样就可以在特征的方法签名中使用该类型。
1
2
3
4
5
| pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
|
Self用来指代当前调用者的具体类型,那么Self::Item就用来指代该类型实现中定义的Item类型:
1
2
3
4
5
6
7
8
9
10
11
12
| impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
//...
}
}
fn main() {
let c = Counter{..}
c.next()
}
|
上述代码中,Counter类型实现了Iterator特征,变量c是特征Iterator的实例,也是next方法的调用者。
为什么不使用泛型:
1
2
3
| pub trait Iterator<Item>{
fn next(&mut self) -> Option<Item>;
}
|
因为代码的可读性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // 泛型写法
trait Container<A,B> {
fn contains(&self,a: A,b: B) ->bool;
}
fn difference<A,B,C(container:&C) -> i32
where
c: Container<A,B> {...}
// 关联类型实现
trait Container{
type A;
type B;
fn copntains(&self, a:Self::A,b:&Self::B) -> bool;
}
fn differnce<C: Container>(container:&:C) {}
|
默认泛型类型参数
在外部类型上实现外部特征(newtype)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| use std::fmt;
struct Wrapper(Vec<String>);
impl fmt::Display for Wrapper {
fn fmt(&self, f:&mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}]", self.0.join(", "))
}
}
fn main() {
let w = Wrapper(vec![String::from("hello"), String::from("world")]);
println!("w = {}", w);
}
|