99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Rust 附錄 C:可派生的 trait

2023-03-22 15:17 更新
appendix-03-derivable-traits.md
commit c07dddac692848ade6c2112c8e15a7087fbbec45

在本書的各個部分中,我們討論了可應用于結(jié)構(gòu)體和枚舉定義的 derive 屬性。derive 屬性會在使用 derive 語法標記的類型上生成對應 trait 的默認實現(xiàn)的代碼。

在本附錄中提供了標準庫中所有可以使用 derive 的 trait 的參考。這些部分涉及到:

  • 該 trait 將會派生什么樣的操作符和方法
  • 由 ?derive? 提供什么樣的 trait 實現(xiàn)
  • 由什么來實現(xiàn)類型的 trait
  • 是否允許實現(xiàn)該 trait 的條件
  • 需要 trait 操作的例子

如果你希望不同于 derive 屬性所提供的行為,請查閱 標準庫文檔 中每個 trait 的細節(jié)以了解如何手動實現(xiàn)它們。

這里列出的 trait 是僅有的在標準庫中定義且能通過 derive 在類型上實現(xiàn)。標準庫中定義的其它 trait 不能通過 derive 在類型上實現(xiàn)。這些 trait 不存在有意義的默認行為,所以由你負責以合理的方式實現(xiàn)它們。

一個無法被派生的 trait 的例子是為終端用戶處理格式化的 Display 。你應該時??紤]使用合適的方法來為終端用戶顯示一個類型。終端用戶應該看到類型的什么部分?他們會找出相關(guān)部分嗎?對他們來說最相關(guān)的數(shù)據(jù)格式是什么樣的?Rust 編譯器沒有這樣的洞察力,因此無法為你提供合適的默認行為。

本附錄所提供的可派生 trait 列表并不全面:庫可以為其自己的 trait 實現(xiàn) derive,可以使用 derive 的 trait 列表事實上是無限的。實現(xiàn) derive 涉及到過程宏的應用,這在第十九章的 “宏” 有介紹。

用于程序員輸出的 Debug

Debug trait 用于開啟格式化字符串中的調(diào)試格式,其通過在 {} 占位符中增加 :? 表明。

Debug trait 允許以調(diào)試目的來打印一個類型的實例,所以使用該類型的程序員可以在程序執(zhí)行的特定時間點觀察其實例。

例如,在使用 assert_eq! 宏時,Debug trait 是必須的。如果等式斷言失敗,這個宏就把給定實例的值作為參數(shù)打印出來,如此程序員可以看到兩個實例為什么不相等。

等值比較的 PartialEq 和 Eq

PartialEq trait 可以比較一個類型的實例以檢查是否相等,并開啟了 == 和 != 運算符的功能。

派生的 PartialEq 實現(xiàn)了 eq 方法。當 PartialEq 在結(jié)構(gòu)體上派生時,只有所有 的字段都相等時兩個實例才相等,同時只要有任何字段不相等則兩個實例就不相等。當在枚舉上派生時,每一個成員都和其自身相等,且和其他成員都不相等。

例如,當使用 assert_eq! 宏時,需要比較比較一個類型的兩個實例是否相等,則 PartialEq trait 是必須的。

Eq trait 沒有方法。其作用是表明每一個被標記類型的值等于其自身。Eq trait 只能應用于那些實現(xiàn)了 PartialEq 的類型,但并非所有實現(xiàn)了 PartialEq 的類型都可以實現(xiàn) Eq。浮點類型就是一個例子:浮點數(shù)的實現(xiàn)表明兩個非數(shù)字(NaN,not-a-number)值是互不相等的。

例如,對于一個 HashMap<K, V> 中的 key 來說, Eq 是必須的,這樣 HashMap<K, V> 就可以知道兩個 key 是否一樣了。

次序比較的 PartialOrd 和 Ord

PartialOrd trait 可以基于排序的目的而比較一個類型的實例。實現(xiàn)了 PartialOrd 的類型可以使用 <、 >、<= 和 >= 操作符。但只能在同時實現(xiàn)了 PartialEq 的類型上使用 PartialOrd。

派生 PartialOrd 實現(xiàn)了 partial_cmp 方法,其返回一個 Option<Ordering> ,但當給定值無法產(chǎn)生順序時將返回 None。盡管大多數(shù)類型的值都可以比較,但一個無法產(chǎn)生順序的例子是:浮點類型的非數(shù)字值。當在浮點數(shù)上調(diào)用 partial_cmp 時,NaN 的浮點數(shù)將返回 None。

當在結(jié)構(gòu)體上派生時,PartialOrd 以在結(jié)構(gòu)體定義中字段出現(xiàn)的順序比較每個字段的值來比較兩個實例。當在枚舉上派生時,認為在枚舉定義中聲明較早的枚舉變體小于其后的變體。

例如,對于來自于 rand crate 中的 gen_range 方法來說,當在一個范圍表達式指定的范圍內(nèi)生成一個隨機值時,PartialOrd trait 是必須的。

Ord trait 也讓你明白在一個帶注解類型上的任意兩個值存在有效順序。Ord trait 實現(xiàn)了 cmp 方法,它返回一個 Ordering 而不是 Option<Ordering>,因為總存在一個合法的順序。只可以在實現(xiàn)了 PartialOrd 和 EqEq 依賴 PartialEq)的類型上使用 Ord trait 。當在結(jié)構(gòu)體或枚舉上派生時, cmp 和以 PartialOrd 派生實現(xiàn)的 partial_cmp 表現(xiàn)一致。

例如,當在 BTreeSet<T>(一種基于有序值存儲數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu))上存值時,Ord 是必須的。

復制值的 Clone 和 Copy

Clone trait 可以明確地創(chuàng)建一個值的深拷貝(deep copy),復制過程可能包含任意代碼的執(zhí)行以及堆上數(shù)據(jù)的復制。查閱第四章 “變量與數(shù)據(jù)交互的方式(二):克隆” 以獲取有關(guān) Clone 的更多信息。

派生 Clone 實現(xiàn)了 clone 方法,其為整個的類型實現(xiàn)時,在類型的每一部分上調(diào)用了 clone 方法。這意味著類型中所有字段或值也必須實現(xiàn)了 Clone,這樣才能夠派生 Clone 。

例如,當在一個切片(slice)上調(diào)用 to_vec 方法時,Clone 是必須的。切片并不擁有其所包含實例的類型,但是從 to_vec 中返回的 vector 需要擁有其實例,因此,to_vec 在每個元素上調(diào)用 clone。因此,存儲在切片中的類型必須實現(xiàn) Clone。

Copy trait 允許你通過只拷貝存儲在棧上的位來復制值而不需要額外的代碼。查閱第四章 “只在棧上的數(shù)據(jù):拷貝” 的部分來獲取有關(guān) Copy 的更多信息。

Copy trait 并未定義任何方法來阻止編程人員重寫這些方法或違反不需要執(zhí)行額外代碼的假設。盡管如此,所有的編程人員可以假設復制(copy)一個值非???。

可以在類型內(nèi)部全部實現(xiàn) Copy trait 的任意類型上派生 Copy。一個實現(xiàn)了 Copy 的類型必須也實現(xiàn)了 Clone,因為一個實現(xiàn)了 Copy 的類型也簡單地實現(xiàn)了 Clone,其執(zhí)行和 Copy 相同的任務。

Copy trait 很少使用;實現(xiàn) Copy 的類型是可以優(yōu)化的,這意味著你無需調(diào)用 clone,這讓代碼更簡潔。

任何使用 Copy 的代碼都可以通過 Clone 實現(xiàn),但代碼可能會稍慢,或者不得不在代碼中的許多位置上使用 clone。

固定大小的值到值映射的 Hash

Hash trait 可以實例化一個任意大小的類型,并且能夠用哈希(hash)函數(shù)將該實例映射到一個固定大小的值上。派生 Hash 實現(xiàn)了 hash 方法。hash 方法的派生實現(xiàn)結(jié)合了在類型的每部分調(diào)用 hash 的結(jié)果,這意味著所有的字段或值也必須實現(xiàn)了 Hash,這樣才能夠派生 Hash。

例如,在 HashMap<K, V> 上存儲數(shù)據(jù),存放 key 的時候,Hash 是必須的。

默認值的 Default

Default trait 使你創(chuàng)建一個類型的默認值。 派生 Default 實現(xiàn)了 default 函數(shù)。default 函數(shù)的派生實現(xiàn)調(diào)用了類型每部分的 default 函數(shù),這意味著類型中所有的字段或值也必須實現(xiàn)了 Default,這樣才能夠派生 Default 。

Default::default 函數(shù)通常結(jié)合結(jié)構(gòu)體更新語法一起使用,這在第五章的 “使用結(jié)構(gòu)體更新語法從其他實例中創(chuàng)建實例” 部分有討論??梢宰远x一個結(jié)構(gòu)體的一小部分字段而剩余字段則使用 ..Default::default() 設置為默認值。

例如,當你在 Option<T> 實例上使用 unwrap_or_default 方法時,Default trait 是必須的。如果 Option<T> 是 None的話, unwrap_or_default 方法將返回存儲在 Option<T> 中 T 類型的 Default::default 的結(jié)果。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號