1.17.1. 一致性
一致性表示對於給定的型別和方法,只有一種正確的實作選擇。
孤兒規則的意思是,只要特徵或型別其中一方位於本地 crate,您就可以為該型別實作該特徵。 例如:
- 您定義的本地型別可以實作
Debug特徵 - 您可以為
bool實作您本地定義的特徵 - 您無法為
bool實作Debug,因為雙方都不是本地的
孤兒規則有一些例外,我們將在下方討論。
1.17.2. 通用實作
通用實作(也稱為通用實作)是指 Rust 允許為滿足特徵約束的每一個型別提供預設實作。
其模板如下:
impl<T> MyTrait for T where T: ...
Enter fullscreen mode Exit fullscreen mode
這表示為所有實作某特徵的型別實作 MyTrait。
例如:
impl<T: Display> ToString for T {}
Enter fullscreen mode Exit fullscreen mode
這表示為所有實作 Display 的型別實作 ToString。
此範例尚未以模板形式撰寫。以模板形式呈現會是:
impl<T> ToString for T where T: Display {}
Enter fullscreen mode Exit fullscreen mode
請注意,只有定義該特徵的 crate 才允許使用通用實作。為既有特徵新增通用實作屬於破壞性變更。
1.17.3. 基礎型別
某些型別極為基礎,我們需要允許任何人為其實作特徵,即使這會違反孤兒規則。這些型別會被標記為 #[fundamental],目前包含 &T、&mut T、Box<T> 與 Pin<P>。
- 額外提醒:
Pin<P>的主要用途是確保值不會被移動,也就是防止std::mem::replace、std::mem::swap或std::mem::take等操作改變該值的實體位址 - 就孤兒規則而言,這些型別在進行孤兒規則檢查之前實際上會被抹除
注意:為基礎型別使用通用實作同樣視為破壞性變更。
1.17.4. 覆蓋實作
有時您需要為外部型別實作外部特徵,這稱為覆蓋實作。這使用了孤兒規則所建立的一個狹義豁免:允許在非常特定的情況下,為外部型別實作外部特徵。
注意:covered implementation 可指 Covered Implementation 或 Override Implementation。此處指的是 Covered Implementation。Override implementation 意指當結構體實作特徵並提供自己的方法時,可以覆寫預設實作。
此形式的模板如下:
impl<P1..=Pn> ForeignTrait<T1..=Tn> for T0
Enter fullscreen mode Exit fullscreen mode
-
P1..=Pn與T1..=T0指多個參數
只有在符合以下所有條件時,才允許此形式:
T1..=Tn中至少有一個是本地型別- 在第一個此類本地型別之前,不得出現
T(其中T是P1..=Pn中的泛型型別之一) - 泛型型別參數
P可以出現在T0..Ti中,只要它被某種中間型別包覆- 若
T作為另一型別的型別參數出現,例如Vec<T>,則視為已包覆 - 若
T單獨出現,或位於基礎型別如&T之後,則視為未包覆
- 若
簡單範例如下:
impl From<MyType> for Vec<i32>
Enter fullscreen mode Exit fullscreen mode
這為外部型別 Vec<i32> 實作了外部特徵 From<MyType>。
以下是更複雜的範例。您可以使用上述規則來理解它們:
| 實作 | 是否有效? |
|---|---|
impl<T> From<T> for MyType |
OK |
impl<T> From<T> for MyType<T> |
OK |
impl<T> From<MyType> for Vec<T> |
OK |
impl<T> ForeignTrait<MyType, T> for Vec<T> |
OK |
-------------------------------------------- |
------------ |
impl<T> ForeignTrait for T |
Not OK |
impl<T> From<T> for T |
Not OK |
impl<T> From<Vec<T>> for T |
Not OK |
impl<T> From<MyType<T>> for T |
Not OK |
impl<T> From<T> for Vec<T> |
Not OK |
impl<T> ForeignTrait<T, MyType> for Vec<T> |
Not OK |
覆蓋實作是否為破壞性變更,取決於具體情況:
- 為既有特徵新增實作,且至少包含一個符合上述條件的新本地型別,屬於非破壞性變更
- 為既有特徵新增不符合上述條件的實作,屬於破壞性變更
注意:
-
impl<T> ForeignTrait<MyType, T> for Vec<T>是有效的 -
impl<T> ForeignTrait<T, MyType> for Vec<T>是無效的
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.