documentation for Ord人中,它说

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

这当然是有道理的,而且可以很容易地存档,如下面的示例所示:

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

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

我测试了循环依赖性和stuff in a playground的问题,但这和我预期的一样有效.互联网也没有产生任何结果.

我能想到的另一个原因是derive个宏现在是如何工作的.人们可能需要用derive(Ord)来替换每一个derive(PartialOrd, Ord)(或者让PartialOrd的宏更智能——我不知道它是否能变得那么智能).

添加建议的一揽子IML将禁止定制PartialOrd的实现,并消除对一致性的要求.当然,这将是图书馆的一个突破性变化.这是唯一的原因,还是我遗漏了其他一些论点?

推荐答案

对于实现PartialOrd的类型,最好使用Ord的总体实现.这样一个全面的实现之所以不存在,是因为它在技术上是不可能的.仅将impl<T: Ord> PartialOrd for T块添加到core将导致错误:

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;

core中已经有一个全面的实现,它实现了PartialOrdPartialOrd类型的所有引用.通过对all个实现Ord的类型实现PartialOrd,就有可能对同一类型实现两次PartialOrd.这样就不清楚应该使用哪种实现.考虑这个代码:

#[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");
    }
}

以下是在X人中实现的特征

  • X: PartialOrd(直接实施),panic 1
  • &X: PartialOrd(参考的全面实施),对1感到panic
  • &X: Ord(直接实施),panic 2

但是,如果我们自动实现PartialOrd,那么将有一个额外的PartialOrd&X的实现,这与2panic .如何解决这一问题尚不明确.

解决方法是使用专门化,这是Rust中不稳定的特性,在Rust 1.0发布时甚至不存在.因此,不实施PartialOrd是唯一的 Select .专门化允许同一项以明确的方式具有多个冲突的trait实现,但它目前不稳定、不可靠,而且只在夜间使用.见this Rust issue for more details on the issue.

Rust相关问答推荐

使用DeliverProcess W或ShellExecuteExW复制Windows Run行为?

使用InlineTables序列化toml ArrayOfTables

为什么我需要在这个代码示例中使用&

在Rust中宏的表达式中提取对象

在决定使用std::Sync::Mutex还是使用Tokio::Sync::Mutex时,操作系统线程调度是考虑因素吗?

我如何使用AWS SDK for Rust获取我承担的角色的凭据?

对reqwest提供的这种嵌套JSON struct 进行反序列化

在 Rust 中,在需要引用 self 的 struct 体方法中使用闭包作为 while 循环条件

使用启用优化的 alloc 会导致非法指令崩溃

Rust中的一生语法有什么作用?

为什么不能在 Rust 中声明静态或常量 std::path::Path 对象?

在 Rust 中,我如何处理请求 javascript 的页面?

无法理解 Rust 对临时值的不可变和可变引用是如何被删除的

Rust 中函数的类型同义词

为什么 &i32 可以与 Rust 中的 &&i32 进行比较?

Rust,我如何正确释放堆分配的内存?

如何用另一个变量向量置换 rust simd 向量?

如何将 u8 切片复制到 u32 切片中?

如何在 Rust 中构建一个 str

在 Rust 中组合特征的不同方法是否等效?