【问题标题】:How to implement the Ord trait without getting the error "use of unstable library feature 'clamp'"?如何实现 Ord 特征而不出现错误“使用不稳定的库功能'clamp'”?
【发布时间】:2020-03-10 04:57:28
【问题描述】:

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

我是这样实现的:

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。

【问题讨论】:

  • 很难回答您的问题,因为它不包含minimal reproducible example。我们无法分辨代码中存在哪些 crate(及其版本)、类型、特征、字段等。如果您尝试在Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易为您提供帮助,否则在全新的 Cargo 项目中,然后在edit 您的问题中包含附加信息。您可以使用Rust-specific MRE tips 来减少您在此处发布的原始代码。谢谢!
  • 一个不安全的clamp trait 方法——它不是unsafe,不清楚你为什么这么认为。
  • 按您的要求添加了游乐场链接。

标签: rust clamp


【解决方案1】:

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

那是因为Ord::clamp 方法不稳定 — 编译器没有骗你。但是,这是一个带有default implementation 的方法,因此您不需要实现它(也不应该实现它,除非您可以改进默认实现)。

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

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

那么您必须为cmp() 定义一个实现。您可能会发现在您的类型字段上使用 cmp() 很有用。

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

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

您的整个代码可能是

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

另见:

【讨论】:

  • “另见”中的第一个链接对我有用。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-07
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多