【问题标题】:When is it appropriate to require only PartialEq and not Eq?什么时候只需要 PartialEq 而不需要 Eq 才合适?
【发布时间】:2019-03-12 18:54:26
【问题描述】:

我正在阅读the Rust book 并试图了解PartialEqEq 特征的用例。

我意识到PartialEq 用于不一定是自反的关系(即可以有这样的xx != x)并且Eq 是一个标记特征,它表示关系也是自反的(现在是适当的等价关系)。

书中给出了一个示例,其中PartialEq 不够,Eq 是必需的:HashMap<K, V> 查找。事实上,如果我们使用只实现PartialEq 的数据类型(例如浮点数)作为键,当我们尝试使用NaN 作为键时会遇到麻烦,因为我们将无法找到它。

现在,我正在尝试了解查找的哪些功能使其需要Eq。如果我找到一个不需要Eq 的代码示例,我可能会更好地理解它。

这本书说assert_eq! 只需要PartialEq 以便我们能够比较事物是否相等。但是如果我们在测试中写assert_eq!(f64::NAN, some_code_producing_nan());,测试总是会失败。我们遇到了与在HashMap 中使用PartialEq 键相同的基本问题,但出于某种原因,它在这里被认为是合适的。

仅需要PartialEq 并添加Eq 的合理函数的示例是不可取/没有意义的?

如果没有这样的用例,那我们为什么要关心将其分成两个特征PartialEq/Eq?例如,Haskell 只有Eq

【问题讨论】:

  • 你在考虑浮点数时会极大地损害自己的利益,因为在浮点数上,相等几乎从来都不是正确的操作。还有其他类型。
  • “如果我找到一个不需要 Eq 的代码示例,我可能会更好地理解它。” -- 我认为您对你的问题在这里。为什么不直接向您解释为什么HashMap 需要Eq?对于assert_eq!,您已经假设“我们有相同的基本问题”,但这是一个没有根据的假设(因为您已经承认您不知道这个问题是什么) .
  • @Shepmaster 好吧,浮点数上的相等是一个很好而简单的关系示例,它不是自反的,但几乎每个人都知道......它甚至出现在这里:en.wikipedia.org/wiki/Partial_equivalence_relation
  • @BenjaminLindley 嗯,但我理解为什么HashMap 需要Eq:以便它能够找到所有的密钥。拥有Eq 意味着我们没有x 这样的值x != x。这对查找有意义。但是当我们不需要Eq 并且只为PartialEq 提供内容时,有哪些示例?自反性是一个很好的属性,为什么要放弃它而只使用PartialEq?如果我们总是想要Eq,那为什么还要有PartialEq trait?
  • @SpencerPark 这是一个非常清晰的解释,包含在少量的单词中,赞。 in the book 的解释在技术上说了同样的话,但不是很清楚。这应该是一个真正的答案。

标签: rust traits


【解决方案1】:

决定何时使用PartialEqEq 应该基于使用是否需要x == x

问题不在于是否可以将xx 进行比较,而是如果发生这种比较,使用是否取决于x==x 始终持有?如果答案是肯定的,请使用Eq。否则更喜欢较弱的约束PartialEq

assert_eq!doesn't 依赖于 x==x 始终保持,因此无需对调用者强制执行该约束。正如 OP 在 cmets 中简洁地提到的 2 个示例:

如果我们使用assert_eq!(NAN, produces_nan()) - 它给出false 是我们的问题,但是如果我们在HashMap 中查找NAN 键,这将是HashMap 的问题,因为它会违反它的查找契约(它应该能够找到放在地图中的所有键)

【讨论】:

  • 我在想更多的尝试:1)想出更多非自反类型的例子(除了浮点数和包含它们的结构)和 2)想出任何其他有用的函数,只需要PartialEq 与 Eq 相对。我找不到任何东西,所以我开始认为 PartialEq 与 Eq 分离的所有这些业务都是由浮点数和 NaN 引起的,并且希望控制诸如浮点数排序向量等潜在错误的类型(这将起作用“随机”在 NaN 的礼物中)。
猜你喜欢
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 2017-05-23
  • 1970-01-01
  • 2018-12-10
  • 2010-12-29
  • 2017-07-13
相关资源
最近更新 更多