所面對的問題:trait泛型 與 所關(guān)聯(lián)的對象的具體類型,解決目標(biāo)類型涉及泛型類別較多的情況,使代碼更具可讀性
關(guān)聯(lián)類型定義:一個將類型占位符與 trait 相關(guān)聯(lián)的方式,這樣 trait 的方法簽名中就可以使用這些占位符類型。trait 的實現(xiàn)者會針對特定的實現(xiàn)在這個類型的位置指定相應(yīng)的具體類型。如此可以定義一個使用多種類型的 trait,直到實現(xiàn)此 trait 時都無需知道這些類型具體是什么。
此外,關(guān)聯(lián)類型只能在impl trait 時對同一個對象實現(xiàn)一次,而泛型則可以對同一個對象實現(xiàn)多次。
// 定義trait,以及實際目標(biāo)類型可能涉及的類型
pub trait Watch {
type Item;
fn inner(&self) -> Option<Self::Item>;
}
// 定義目標(biāo)類型
struct A {
data: i32,
}
// 在對象上實現(xiàn)trait,并將實際數(shù)據(jù)類型涉及的類型與trait預(yù)設(shè)的關(guān)聯(lián)類型連接
impl Watch for A {
// 棧類型,自動copy
type Item = i32;
// (Self)指:A;(type Item = i32)指:將與A相關(guān)聯(lián)的類型放入類型占位符<Item>之中
fn inner(&self) -> Option<Self::Item> {
Some(self.data)
}
}
// 定義新的目標(biāo)類型
struct B {
data: String,
}
// 同理
impl Watch for B {
// 堆類型,需clone
type Item = String;
fn inner(&self) -> Option<Self::Item> {
Some(self.data.clone())
}
}
// 調(diào)用
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 中的泛型與關(guān)聯(lián)類型,有如下區(qū)別:
- 如果 trait 中包含泛型參數(shù),那么,可以對同一個目標(biāo)類型,多次 impl 此 trait,每次提供不同的泛型參數(shù)。而關(guān)聯(lián)類型方式只允許對目標(biāo)類型實現(xiàn)一次。
- 如果 trait 中包含泛型參數(shù),那么在具體方法調(diào)用的時候,必須加以類型標(biāo)注以明確使用的是哪一個具體的實現(xiàn)。而關(guān)聯(lián)類型方式具體調(diào)用時不需要標(biāo)注類型(因為不存在模棱兩可的情況)。
https://blog.csdn.net/u012067469/article/details/103725084