当前位置: 首页 > 知识库问答 >
问题:

为什么'ParatalOrd'不是针对所有实现'Ord'的类型实现的?

从焱
2023-03-14

Ord的留档中,它说

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

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

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

我想知道,为什么他们会把这个负担/风险留给我们用户,而不是用毯子

我在操场上测试了循环依赖和其他东西的问题,但这和我预期的一样有效。互联网也没有产生任何结果。

我能想到的另一个原因是派生宏现在是如何工作的。人们可能必须将每个派生(PartialOrd,Ord)替换为派生(Ord)(或者将派生(Ord)(PartialOrd)的宏变得更智能-我不知道它是否能变得如此智能)。

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

共有2个答案

汪信鸥
2023-03-14

显然,在github的一个问题——rust lang/rust#63104中提到了这一点:

这与内核中现有的一揽子impl相冲突。

error[E0119]: conflicting implementations of trait `std::cmp::PartialOrd<&_>` > for type `&_`:
 --> src/lib.rs:3:1
  |
3 | impl<T: Ord> PartialOrd for T {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<A, B> std::cmp::PartialOrd<&B> for &A
            where A: std::cmp::PartialOrd<B>, A: ?Sized, B: ?Sized;
微生自怡
2023-03-14

对于实现PartialOrd的类型,最好使用Ord的全面实现。这样一个全面的实现之所以不存在,是因为它在技术上是不可能的。只需添加一个impl

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中已经有一个全面的实现,它为PartialOrd类型的所有引用实现了PartialOrd。通过对所有实现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: ParatalOrd(直接实现),恐慌与1

但是如果我们要自动实现PartialOrd,那么在

解决方法是使用专门化,这是Rust中不稳定的特性,在Rust 1.0发布时甚至不存在。因此,不实施PartialOrd是唯一的选择。专门化允许同一项以一种明确的方式具有多个冲突的trait实现,但它目前不稳定、不可靠,而且只在夜间进行。有关此问题的更多详细信息,请参阅此生锈问题。

 类似资料:
  • 我有一个新类型,我想实现: 当我尝试比较我的类型的两个变量时,会出现错误: 当我实现,和(,,,,)时,一切都很好,但如果我提供,我们可以推断出和之类的函数!这是多余的!我不喜欢这个! 当查看文档时,我在的定义中看到了这一点: 这看起来像是从和继承的特征。为什么trait不能使用函数为继承的trait提供所需方法的默认实现?我不知道遗传特性是如何起作用的,搜索也没有什么用处,但我认为这应该是可能的

  • 我想要一个方法,用于、和,因此我创建了一个trait: 我得到一个错误: 根据Rust标准库文档,未实现。为什么存在冲突的实现?

  • 问题内容: 我对Python 3中的和类有些困惑。也许有人可以消除我的困惑或提供一些其他信息。 我目前的理解是,每个类(除外)都从称为的基类继承。但是每个类(包括)也是该类的一个实例,它是自身的实例,并且也从继承。 我的问题是: 是否有一个原因/设计决策,为什么是的实例并从中继承?对象的/ class是否也可以是对象本身? 类()如何成为其自身的实例? 哪一个是真正的基类或? 我一直认为这将是最“

  • 我有一个问题: 多个结构实现一个trait 都可以以相同的方式实现trait 我考虑过写这个(简短版本) 游戏场 这无法编译: 这里怎么了?或者有没有其他方法可以通用地实现此,而不必为和分别键入一次? 谢谢你们

  • 或者“为什么Sun/Oracle的家伙每次都强迫我们重写equals()和hashCode()?” 每个人都知道,如果你覆盖一个对象的equals()或hashCode(),你也必须覆盖另一个,因为这两者之间有一个约定: 请注意,每当重写hashCode方法[e.equals()]时,通常有必要重写该方法,以维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码。-对象的API文档