为什么我在f32上没有实现Ord时会收到“trait的冲突实现”?

5

我希望有一个针对 f32, u32i32min() 方法,因此我创建了一个名为 Min 的 trait:

trait Min {
    fn min(v1: Self, v2: Self) -> Self;
}

impl<T> Min for T where T: Ord {
    fn min(v1: Self, v2: Self) -> Self {
        ::std::cmp::min(v1, v2)
    }
}

impl Min for f32 {
    fn min(v1: Self, v2: Self) -> Self {
        v1.min(v2)
    }
}

I get an error:

error[E0119]: conflicting implementations of trait `Min` for type `f32`:
  --> src/main.rs:11:1
   |
5  | / impl<T> Min for T where T: Ord {
6  | |     fn min(v1: Self, v2: Self) -> Self {
7  | |         ::std::cmp::min(v1, v2)
8  | |     }
9  | | }
   | |_- first implementation here
10 | 
11 | / impl Min for f32 {
12 | |     fn min(v1: Self, v2: Self) -> Self {
13 | |         v1.min(v2)
14 | |     }
15 | | }
   | |_^ conflicting implementation for `f32`

根据 Rust 标准库文档,f32 没有实现 Ord 接口。为什么会出现冲突的实现呢?

2
@erip 看起来 f32 只实现了 PartialOrd - Laurence
哇,这似乎是一个bug。只有通用实现,编译器明确表示f32没有实现Ord,但在OP的示例中,它认为f32实现了通用实现。 - Boiethios
@Laurence 哎呀。:) 感谢您让我保持诚实。 - erip
1个回答

6
我认为这是因为编译器不能排除某天会有人为f32实现Ord的可能性。换句话说,如果编译器不保守行事,任何新的特性都会对现有类型造成破坏变化,这将严重限制每个库在不破坏所有使用者的情况下增长的能力。
对于这一点,语言设计上有意做了选择,没有直接的绕过方法。最接近的方法是实现一个包装类型f32(比如struct OrdF32(f32);)并在其上实现OrdMin,或使用一个定义了这样一个包装类型的crate(例如ordered-float)。

如何解决这个问题? - Boiethios
1
@Boiethios:你不需要这样做;我在我的回答中添加了更多内容。 - DK.
1
@Laurence:我所知道的最接近的是RFC 1023,但如果那证明太难理解,那么我不知道有什么更能更...连贯地解释它的了。 - DK.
1
@Laurence,这些被称为孤儿规则,如果我没记错的话。请参考RFC 1023错误0210 - Shepmaster
1
@9000:你不能f32实现Ord,因为它不满足要求:它不是完全有序的。即使它满足要求,你也不能这样做,因为你不能在你没有定义的类型上实现一个你没有编写的特性。 - DK.
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接