如何在不出现错误 "use of unstable library feature 'clamp'" 的情况下实现 Ord 特性?

How to implement the Ord trait without getting the error "use of unstable library feature 'clamp'"?

我有一个结构,我想将它用作 BTreeMap 中的键,所以我实现了 PartialEqEqPartialOrdOrd.最后一个会导致问题,因为存在不安全的 clamp 特征方法。

我是这样实现的:

use std::cmp::Ordering;

#[derive(Debug, Eq, Copy, Clone)]
struct Baz(usize);

impl PartialEq for Baz {
    fn eq(&self, other: &Self) -> bool {
        self.0.eq(&other.0)
    }

    fn ne(&self, other: &Self) -> bool {
        self.0.ne(&other.0)
    }
}

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

    fn lt(&self, other: &Self) -> bool {
        self.0.lt(&other.0)
    }

    fn le(&self, other: &Self) -> bool {
        self.0.le(&other.0)
    }

    fn gt(&self, other: &Self) -> bool {
        self.0.gt(&other.0)
    }

    fn ge(&self, other: &Self) -> bool {
        self.0.ge(&other.0)
    }
}

impl Ord for Baz {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }

    fn max(self, other: Self) -> Self
    where
        Self: Sized,
    {
        Self(self.0.max(other.0))
    }

    fn min(self, other: Self) -> Self
    where
        Self: Sized,
    {
        Self(self.0.min(other.0))
    }

    fn clamp(self, min: Self, max: Self) -> Self
    where
        Self: Sized,
    {
        Self(self.0.clamp(min.0, max.0))
    }
}

fn main() {
    Baz(1);
}

Playground

据我所知,整数钳位是安全的并且应该可以正常工作,但是 Rust 给我错误

error[E0658]: use of unstable library feature 'clamp'
  --> src/main.rs:57:5
   |
57 | /     fn clamp(self, min: Self, max: Self) -> Self
58 | |     where
59 | |         Self: Sized,
60 | |     {
61 | |         Self(self.0.clamp(min.0, max.0))
62 | |     }
   | |_____^
   |
   = note: for more information, see https://github.com/rust-lang/rust/issues/44095

error[E0658]: use of unstable library feature 'clamp'
  --> src/main.rs:61:21
   |
61 |         Self(self.0.clamp(min.0, max.0))
   |                     ^^^^^
   |
   = note: for more information, see https://github.com/rust-lang/rust/issues/44095

我该如何解决这个问题?我正在使用 Rust 1.41。

As far as I know, clamp for integers is safe and should work just fine, but Rust gives me the error

那是因为 Ord::clamp method is unstable — the compiler isn't lying to you. However, that's a method with a default implementation,所以您不需要实现它(也不应该,除非您可以改进默认实现)。

有用的是,Ord 的文档中有一个标题为 How can I implement Ord? 的部分,它准确描述了您需要做什么:

Ord requires that the type also be PartialOrd and Eq (which requires PartialEq).

Then you must define an implementation for cmp(). You may find it useful to use cmp() on your type's fields.

特别相关的是 Ord 可以推导出:

This trait can be used with #[derive]. When derived on structs, it will produce a lexicographic ordering based on the top-to-bottom declaration order of the struct's members. When derived on enums, variants are ordered by their top-to-bottom declaration order.

您的整个代码可能是

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
struct Baz(usize);

另请参阅: