0

我有一个结构,我想将其用作 中的键,BTreeMap因此我实现了PartialEqEq和. 最后一个会导致问题,因为存在不安全的trait 方法。PartialOrdOrdclamp

我以这种方式实现它:

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);
}

操场

据我所知,整数的钳位是安全的,应该可以正常工作,但是 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。

4

1 回答 1

1

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

那是因为该Ord::clamp方法是不稳定的——编译器不会对你撒谎。但是,这是一种具有默认实现的方法,因此您不需要实现它(也不应该实现,除非您可以改进默认实现)。

有帮助的是,文档中有一个Ord标题为“如何实现 Ord? ”的部分。它准确地描述了您需要做的事情:

Ord要求类型也是PartialOrdand Eq(需要PartialEq)。

然后,您必须为cmp(). cmp()您可能会发现在您的类型字段上使用它很有用。

特别相关的是Ord可以得出的事实:

此特征可与#[derive]. 当derived 在结构上时,它将根据结构成员的从上到下的声明顺序生成字典顺序。当derived 在枚举上时,变体按其从上到下的声明顺序排序。

您的整个代码可能是

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

也可以看看:

于 2020-03-09T20:48:08.177 回答