所面对的问题:trait泛型 与 所关联的对象的具体类型,解决目标类型涉及泛型类别较多的情况,使代码更具可读性
关联类型定义:一个将类型占位符与 trait 相关联的方式,这样 trait 的方法签名中就可以使用这些占位符类型。trait 的实现者会针对特定的实现在这个类型的位置指定相应的具体类型。如此可以定义一个使用多种类型的 trait,直到实现此 trait 时都无需知道这些类型具体是什么。
此外,关联类型只能在impl trait 时对同一个对象实现一次,而泛型则可以对同一个对象实现多次。
// 定义trait,以及实际目标类型可能涉及的类型
pub trait Watch {
type Item;
fn inner(&self) -> Option<Self::Item>;
}
// 定义目标类型
struct A {
data: i32,
}
// 在对象上实现trait,并将实际数据类型涉及的类型与trait预设的关联类型连接
impl Watch for A {
// 栈类型,自动copy
type Item = i32;
// (Self)指:A;(type Item = i32)指:将与A相关联的类型放入类型占位符<Item>之中
fn inner(&self) -> Option<Self::Item> {
Some(self.data)
}
}
// 定义新的目标类型
struct B {
data: String,
}
// 同理
impl Watch for B {
// 堆类型,需clone
type Item = String;
fn inner(&self) -> Option<Self::Item> {
Some(self.data.clone())
}
}
// 调用
fn main() {
// 新建A对象
let a = A{data: 10};
// 新建B对象
let b = B{data: String::from("B")};
assert_eq!(Some(10), a.inner());
assert_eq!(Some(String::from("B")), b.inner());
}
trait 中的泛型与关联类型,有如下区别:
- 如果 trait 中包含泛型参数,那么,可以对同一个目标类型,多次 impl 此 trait,每次提供不同的泛型参数。而关联类型方式只允许对目标类型实现一次。
- 如果 trait 中包含泛型参数,那么在具体方法调用的时候,必须加以类型标注以明确使用的是哪一个具体的实现。而关联类型方式具体调用时不需要标注类型(因为不存在模棱两可的情况)。
https://blog.csdn.net/u012067469/article/details/103725084
网友评论