为什么“PartialOrd”没有为所有实现“Ord”的类型一揽子实现?

Nik*_*rin 14 rust

在的文档Ord中,它说

实现必须与 PartialOrd 实现一致 [...]

这当然是有道理的,并且可以轻松存档,如下面的示例所示:

impl PartialOrd for MyType {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道,为什么他们会把这种负担/风险留给我们用户而不是有一条毯子impl<T: Ord> PartialOrd for T { /* ... */ }。

我测试了循环依赖问题和游乐场中的东西,但这正如我所期望的那样。互联网也没有产生任何结果。

我能想到的另一个原因是derive宏现在的工作方式。人们可能必须将每个替换derive(PartialOrd, Ord)为 just derive(Ord)(或者使宏变得PartialOrd更智能 - 我不知道它是否可以变得那么智能)。

添加建议的总体实现将禁止自定义实现PartialOrd并消除一致性要求。当然,这对图书馆来说是一个重大改变。这是唯一的原因,还是我在这里遗漏了一些其他论点?

loo*_*ops 9

对于实现的类型来说,全面实现. 之所以不存在这样的一揽子实施,是因为它在技术上是不可能的。仅添加一个块就会导致错误:OrdPartialOrdimpl<T: Ord> PartialOrd for Tcore

error[E0119]: conflicting implementations of trait `std::cmp::PartialOrd<&_>` for type `&_`
 --> src/lib.rs:1:1
  |
1 | impl<T: Ord> PartialOrd for T {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<A, B> PartialOrd<&B> for &A
            where A: PartialOrd<B>, A: ?Sized, B: ?Sized;
Run Code Online (Sandbox Code Playgroud)

已经有一个全面的实现,用于实现所有类型的core引用。通过实现所有实现 的类型,可以为同一类型实现两次。那么应该使用哪种实现就不清楚了。考虑这段代码:PartialOrdPartialOrdPartialOrdOrdPartialOrd

#[derive(PartialEq, Eq)]
struct X;
impl PartialOrd for X {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        panic!("1");
    }
}
impl Ord for &X {
    fn cmp(&self, other: &Self) -> Ordering {
        panic!("2");
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是实施的特征X

  • X: PartialOrd(直接实现),恐慌1
  • &X: PartialOrd(参考的一揽子实施),恐慌1
  • &X: Ord(直接实现),恐慌2

但如果我们要PartialOrd自动实现,那么就会有一个额外的PartialOrdon &Xthat Panics的实现2。该如何解决尚不明确。

解决这个问题的方法是使用专门化,这是 Rust 中一个不稳定的特性,在 Rust 1.0 发布时甚至不存在。因此,不实施PartialOrd是唯一的选择。专业化允许同一个项目以明确的方式拥有多个相互冲突的特征实现,但它目前不稳定、不健全且仅限夜间。有关该问题的更多详细信息,请参阅此 Rust 问题。