附录 C:可派生特征

在本书的不同地方,我们讨论了 attribute 这个属性,即 您可以应用于 struct 或 enum 定义。该属性会生成 代码,该代码将在 键入您已使用语法注释的 Sample。derivederivederive

在本附录中,我们提供了标准中所有特征的参考 库,以便与 一起使用。每个部分都涵盖:derive

  • 派生此 trait 的运算符和方法将启用
  • 提供的 trait 的实现有什么作用derive
  • 实现 trait 对类型意味着什么
  • 允许或不允许您实施 trait 的条件
  • 需要 trait 的作示例

如果您希望的行为与 attribute 提供的行为不同, 有关如何手动实施它们的详细信息,请参阅每个特征的标准库文档derive

此处列出的这些特征是标准库定义的唯一特征 可以使用 .在 standard 库没有合理的默认行为,因此由您来 以对您要完成的任务有意义的方式实施它们。derive

无法派生的特征的一个示例是 ,它处理 面向最终用户的格式设置。您应该始终考虑适当的方式 向最终用户显示类型。最终用户应为类型的哪些部分 允许查看?他们认为哪些部分相关?数据的格式 对他们来说最相关吗?Rust 编译器没有这个洞察力,所以 它无法为您提供适当的默认行为。Display

本附录中提供的可衍生特征列表并不全面: 库可以实现自己的 trait,将 你可以用的特征 真正的开放式.实现涉及使用过程宏,这在第 19 章的 “宏” 一节中介绍。derivederivederive

Debug for Programmer 输出

该 trait 支持在格式字符串中进行调试格式化,你可以 通过在占位符内添加来指示。Debug:?{}

该 trait 允许您打印类型的实例以进行调试 目的,以便您和其他使用您的类型的程序员可以检查实例 在程序执行的特定点。Debug

例如,在使用宏时,该特征是必需的。 如果相等 断言失败,因此程序员可以看到为什么这两个实例不相等。Debugassert_eq!

用于相等比较的 PartialEqEq

该 trait 允许您比较要检查的类型的实例 相等,并允许使用 and 运算符。PartialEq==!=

派生实现该方法。何时派生于 structs 中,只有当所有字段都相等时,两个实例才相等,并且 如果任何字段不相等,则实例不相等。当在枚举上派生时, 每个变体都等于自身,不等于其他变体。PartialEqeqPartialEq

例如,使用宏时,该特征是必需的,该宏需要能够比较一种类型的两个实例 为了平等。PartialEqassert_eq!

trait 没有方法。其目的是表示对于每个 的 annotated 类型,则值等于自身。trait 只能为 应用于也实现 的类型,尽管不是所有 implement 可以实现 .这方面的一个例子是浮点 Number types:浮点数的实现表明两个 not-a-number () 值的实例彼此不相等。EqEqPartialEqPartialEqEqNaN

when is required 的一个示例是 a 中的 key ,因此可以判断两个 key 是否相同。EqHashMap<K, V>HashMap<K, V>

用于排序比较的 PartialOrdOrd

该 trait 允许您比较类型的实例以进行排序 目的。implements 的类型可以与 、 、 和 运算符一起使用。您只能将 trait 应用于类型 也实现 .PartialOrdPartialOrd<><=>=PartialOrdPartialEq

派生实现了该方法,该方法返回一个 that 将在给定的值不产生 订购。一个不产生排序的值示例,即使 该类型的大多数值都可以比较,是非数字 () 浮点数 点值。使用任何浮点数和浮点值进行调用都将返回 。PartialOrdpartial_cmpOption<Ordering>NoneNaNpartial_cmpNaNNone

在 structs 上派生时,通过比较 值 (value ) 中字段在结构体中出现的顺序 定义。当在枚举上派生时,之前在 enum 定义被视为小于后面列出的变体。PartialOrd

该特征是必需的,例如,对于 method 从生成 Random Value 的 crate 中,该 crate 的 random 值范围由 range 表达式。PartialOrdgen_rangerand

该 trait 允许您知道,对于带注释的 type,则存在有效的排序。trait 实现了 它返回一个而不是一个,因为一个有效的 订购总是可能的。您只能将 trait 应用于类型 ,这也实现 和 (和 需要 )。什么时候 derived 的行为方式与派生的 的实现 与 。OrdOrdcmpOrderingOption<Ordering>OrdPartialOrdEqEqPartialEqcmppartial_cmpPartialOrd

何时需要的一个示例是将值存储在 , 一种根据值的排序顺序存储数据的数据结构。OrdBTreeSet<T>

克隆复制以复制值

该 trait 允许您显式创建值的深层副本,并且 复制过程可能涉及运行任意代码和复制堆 数据。请参阅“变量和数据交互的方式: Clone“ 部分 第 4 章,了解有关 的更多信息。CloneClone

派生实现该方法,该方法在为 whole 类型调用类型的每个部分。这意味着所有 类型中的字段或值也必须实现才能派生。CloneclonecloneCloneClone

何时需要的一个示例是在 片。切片不拥有它包含的类型实例,而是 vector returned from 需要拥有其实例,因此会调用每个项目。因此,存储在 slice 中的类型必须实现 .Cloneto_vecto_vecto_veccloneClone

该 trait 允许您通过仅复制存储在 堆栈;不需要任意代码。请参阅“仅堆栈数据: Copy“部分了解更多信息 的信息。CopyCopy

trait 没有定义任何方法来阻止程序员 重载这些方法并违反以下假设:没有任意代码 正在运行。这样,所有程序员都可以假设复制一个值将是 非常快。Copy

您可以在其部分全部实现 .一种类型 implements 还必须实现 ,因为 implements 的类型具有执行与 相同的任务的普通实现。CopyCopyCopyCloneCopyCloneCopy

很少需要该特征;实现的类型具有 优化,这意味着您不必调用 ,这使得 代码更简洁。CopyCopyclone

所有可能的事情也可以通过 来完成,但是 代码可能较慢或必须在某些地方使用。CopyCloneclone

用于将值映射到固定大小值的哈希

该 trait 允许您采用任意大小的 type 实例,并且 使用哈希函数将该实例映射到 fixed size 的值。派生实现该方法。该方法的派生实现结合了对类型的每个部分的调用结果 这意味着所有字段或值也必须实现才能派生 。HashHashhashhashhashHashHash

何时需要的一个例子是将键存储在 中以有效地存储数据。HashHashMap<K, V>

默认值

该特征允许您为类型创建默认值。派生实现函数。函数的派生实现在类型的每个部分上调用函数 这意味着类型中的所有字段或值也必须实现为 获得。DefaultDefaultdefaultdefaultdefaultDefaultDefault

该函数通常与 struct 结合使用 update 语法在“从其他实例创建实例 结构体更新 Syntax“部分。您可以自定义结构体的几个字段,然后 使用 为其余字段设置并使用默认值。Default::default..Default::default()

例如,当您在实例上使用该方法时,该特征是必需的。如果 is ,该方法将返回存储在 .Defaultunwrap_or_defaultOption<T>Option<T>Noneunwrap_or_defaultDefault::defaultTOption<T>

本文档由官方文档翻译而来,如有差异请以官方英文文档(https://doc.rust-lang.org/)为准