Rust 常见内置 Traits 详解(一)

Rust 常见内置 Traits 详解(一)

💡 原文中文,约2900字,阅读约需7分钟。
📝

内容提要

本文介绍了 Rust 中的内置 Traits,包括 Eq、PartialEq、Ord 和 PartialOrd。Eq 和 PartialEq 用于定义值的相等性,Ord 和 PartialOrd 用于定义值的顺序。实现这些 Traits 需遵循特定的数学性质,如对称性、传递性和反对称性。可以通过 #[derive] 自动实现这些 Traits,简化代码。

🔎

延伸解读

Eq 与 PartialEq 的核心区别

Eq 和 PartialEq 都用于定义相等性,但关键区别在于反身性。PartialEq 只要求对称性和传递性,而 Eq 还要求反身性,即 a == a 必须成立。浮点数类型只实现了 PartialEq 而非 Eq,因为 NaN != NaN 违反了反身性。因此,当类型可能包含 NaN 时,只能使用 PartialEq。

Ord 与 PartialOrd 的数学性质

Ord 表示全序,要求满足反对称性、传递性和连通性;PartialOrd 表示偏序,只要求反对称性和传递性,无需连通性。连通性意味着任意两个值都可比较,而 PartialOrd 允许不可比较的情况,例如浮点数中的 NaN。实现时,PartialOrd 的 partial_cmp 返回 Option<Ordering>,而 Ord 的 cmp 直接返回 Ordering。

自动派生与手动实现的取舍

通过 #[derive] 可以自动实现 PartialEq、Eq、PartialOrd 和 Ord,编译器会基于结构体字段按声明顺序进行字典序比较。但自动实现可能不符合业务逻辑,例如只希望根据某个字段比较。此时可以手动实现,如示例中根据 height 字段比较 Person。手动实现时需注意保持各 trait 之间的一致性,避免冲突。

实现依赖与注意事项

实现这些 trait 时存在依赖关系:Eq 依赖 PartialEq,Ord 依赖 PartialOrd 和 Eq,PartialOrd 依赖 PartialEq。因此,实现 Ord 时必须同时实现 PartialOrd、Eq 和 PartialEq。此外,手动实现时需确保比较逻辑一致,例如 PartialOrd 的 partial_cmp 应基于 Ord 的 cmp 实现,以避免违反数学性质。

❓

Q&A

Rust 中的 Eq 和 PartialEq 有什么区别?

Eq 需要满足反身性,而 PartialEq 不需要。两者都需满足对称性和传递性。

如何在 Rust 中实现自定义的 PartialEq?

可以通过实现 fn eq(&self, other: &Self) -> bool 方法来自定义 PartialEq。

Ord 和 PartialOrd 的主要用途是什么?

Ord 和 PartialOrd 用于定义值的总序和部分序,分别重载比较运算符。

在 Rust 中如何自动实现 Eq 和 PartialEq?

可以使用 #[derive(Eq)] 和 #[derive(PartialEq)] 来自动实现这些 Traits。

实现 Ord 时需要满足哪些数学性质?

Ord 需要满足反对称性、传递性和连通性。

PartialOrd 和 Ord 之间有什么依赖关系?

PartialOrd 要求实现 PartialEq,Ord 要求实现 PartialOrd 和 Eq。

🏷️

标签

➡️

继续阅读