附录 C:可派生特征
在本书的不同地方,我们讨论了derive属性,其中
您可以应用于 struct 或 enum 定义。这derive属性生成
代码,该代码将在
键入derive语法。
在本附录中,我们提供了标准中所有特征的参考
库derive.每个部分都涵盖:
- 派生此 trait 的运算符和方法将启用
- trait 提供的实现是什么
derivedoes - 实现 trait 对类型意味着什么
- 允许或不允许您实施 trait 的条件
- 需要 trait 的作示例
如果您希望的行为与derive属性
有关如何手动实施它们的详细信息,请参阅每个特征的标准库文档。
此处列出的这些特征是标准库定义的唯一特征
可以使用derive.在
standard 库没有合理的默认行为,因此由您来
以对您要完成的任务有意义的方式实施它们。
无法派生的特征的一个示例是Display,它处理
面向最终用户的格式设置。您应该始终考虑适当的方式
向最终用户显示类型。最终用户应为类型的哪些部分
允许查看?他们认为哪些部分相关?数据的格式
对他们来说最相关吗?Rust 编译器没有这个洞察力,所以
它无法为您提供适当的默认行为。
本附录中提供的可衍生特征列表并不全面:
库可以实现derive对于他们自己的特征,将
您可以使用的特征derive与 TRULY 开放式。实施derive涉及使用过程宏,这在第 19 章的 “宏” 一节中介绍。
Debug用于编程器输出
这Debugtrait 在格式字符串中启用调试格式,而
通过添加:?在占位符中。{}
这Debugtrait 允许您打印某种类型的实例以进行调试
目的,以便您和其他使用您的类型的程序员可以检查实例
在程序执行的特定点。
这Debugtrait 是必需的,例如,在使用assert_eq!宏。
如果相等
断言失败,因此程序员可以看到为什么这两个实例不相等。
PartialEq和Eqfor Equality Comparisons (相等比较)
这PartialEqtrait 允许您比较要检查的类型的实例
相等,并允许使用 和==!=运营商。
推导PartialEq实现eq方法。什么时候PartialEq派生于
structs 中,只有当所有字段都相等时,两个实例才相等,并且
如果任何字段不相等,则实例不相等。当在枚举上派生时,
每个变体都等于自身,不等于其他变体。
这PartialEqtrait 是必需的,例如,使用assert_eq!宏,它需要能够比较一个类型的两个实例
为了平等。
这Eqtrait 没有方法。其目的是表示对于每个
的 annotated 类型,则值等于自身。这Eqtrait 只能是
应用于同时实现PartialEq,尽管并非所有类型
实现PartialEq可以实施Eq.这方面的一个例子是浮点
Number types:浮点数的实现表明两个
非数字 (NaN) 值不相等。
when 的示例Eq是必需的,用于HashMap<K, V>所以HashMap<K, V>可以判断两个 key 是否相同。
PartialOrd和Ord用于排序比较
这PartialOrdtrait 允许您比较类型的实例以进行排序
目的。实现PartialOrd可以与 、 、 和 运算符一起使用。您只能应用<><=>=PartialOrd类型的 trait
也实现PartialEq.
推导PartialOrd实现partial_cmp方法,该方法返回一个Option<Ordering>那将是None当给定的值不会产生
订购。一个不产生排序的值示例,即使
该类型的大多数值都可以比较,是非数字 (NaN) 浮动
点值。叫partial_cmp替换为任何浮点数和NaN浮点值将返回None.
当派生于 structs 时,PartialOrd通过比较
值 (value ) 中字段在结构体中出现的顺序
定义。当在枚举上派生时,之前在
enum 定义被视为小于后面列出的变体。
这PartialOrdtrait 是必需的,例如,对于gen_range方法
从randcrate 生成一个随机值,范围由
range 表达式。
这Ordtrait 允许您知道,对于带注释的
type,则存在有效的排序。这Ordtrait 实现cmp方法
,它返回一个Ordering而不是Option<Ordering>因为有效的
订购总是可能的。您只能应用Ord类型的 trait
也实现PartialOrd和Eq(以及Eq需要PartialEq).什么时候
派生于结构和枚举,cmp的行为方式与派生的
implementation forpartial_cmp与PartialOrd.
when 的示例Ord是必需的,当将值存储在BTreeSet<T>,
一种根据值的排序顺序存储数据的数据结构。
Clone和Copy用于复制值
这Clonetrait 允许您显式地创建值的深层副本,并且
复制过程可能涉及运行任意代码和复制堆
数据。请参阅“变量和数据交互的方式:
Clone“ 部分
第 4 章 了解更多信息Clone.
推导Clone实现clone方法,当为
整个类型,调用clone在类型的每个部分上。这意味着所有
类型中的字段或值也必须实现Clone衍生Clone.
when 的示例Clone是必需的,在调用to_vec方法在
片。切片不拥有它包含的类型实例,而是 vector
返回自to_vec将需要拥有其实例,因此to_vec调用clone在每个项目上。因此,存储在 slice 中的类型必须实现Clone.
这Copytrait 允许您通过仅复制存储在
堆栈;不需要任意代码。请参阅“仅堆栈数据:
Copy“部分了解更多信息
信息Copy.
这Copytrait 没有定义任何方法来防止程序员
重载这些方法并违反以下假设:没有任意代码
正在运行。这样,所有程序员都可以假设复制一个值将是
非常快。
您可以派生Copy在部分全部实现Copy.一种类型
实现Copy还必须实现Clone,因为实现Copy具有Clone执行与Copy.
这Copy性状很少是必需的;实现Copy有
优化,这意味着您不必调用clone,这使得
代码更简洁。
一切皆有可能Copy您还可以使用Clone,但
代码可能更慢或必须使用clone在某些地方。
Hash用于将值映射到固定大小的值
这Hashtrait 允许您获取任意大小的类型的实例,并且
使用哈希函数将该实例映射到 fixed size 的值。推导Hash实现hash方法。的hashmethod 合并调用hash在类型的每个部分上,
这意味着所有字段或值也必须实现Hash衍生Hash.
when 的示例Hash是必需的,用于将密钥存储在HashMap<K, V>以有效地存储数据。
Default对于默认值
这Defaulttrait 允许您为类型创建默认值。推导Default实现default功能。的default函数调用default函数对类型的每个部分执行,
这意味着类型中的所有字段或值也必须实现Default自
获得Default.
这Default::defaultfunction 通常与 struct 结合使用
update 语法在“从其他实例创建实例
结构体更新
Syntax“部分。您可以自定义结构体的几个字段,然后
使用..Default::default().
这Defaulttrait 时需要unwrap_or_default上Option<T>实例。如果Option<T>是None、方法unwrap_or_default将返回Default::default对于类型T存储在Option<T>.
本文档由官方文档翻译而来,如有差异请以官方英文文档(https://doc.rust-lang.org/)为准