【问题标题】:Implementing From/Into for struct with constraints为具有约束的结构实现 From/Into
【发布时间】:2016-10-09 03:18:58
【问题描述】:

由于.max() 不适用于f64s,我正在编写一个ForceOrd 结构来断言参数不是NaN。预期用途类似于:

let m = xs.iter().map(|&x| ForceOrd(x)).max().unwrap().into();

但是,我无法让 Into 特征实现编译错误:

conflicting implementations of trait `std::convert::Into<_>` for type `ForceOrd<_>`

代码(playground):

#[derive(PartialEq, PartialOrd)]
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X);
impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { }
impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.0.partial_cmp(&other.0).unwrap()
    }
}
/// doesn't work
impl<X: PartialEq + PartialOrd> Into<X> for ForceOrd<X> {
    fn into(x: Self) -> X { x.0 }
}
/// doesn't work either
impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X {
    fn from(x: ForceOrd<X>) -> Self { x.0 }
}

【问题讨论】:

  • 放宽对此的通用约束并直接在 f64 上实现它应该可行吗?这不是你的选择吗?我认为不可能像您那样将特征边界添加到跨板条箱的开放泛型中(如果您实现 just From,这应该是您遇到的错误)

标签: rust traits


【解决方案1】:

您不能同时为单一类型实现 FromInto,即,如果您还 impl Into&lt;X&gt; for ForceOrd&lt;X&gt;,则不能 impl From&lt;ForceOrd&lt;X&gt;&gt; for X。你也只需要一个。作为IntoFrom 的文档,这两个状态:

From<T> for U implies Into<U> for T

您可能应该只使用From 实现。您可以查看以下问题以获取一般选择的信息:When should I implement std::convert::From vs std::convert::Into?

编辑:因为实现From(在这种情况下)不像删除impl Into那么简单,下面你可以看到f64如何实现这一点:

#[derive(PartialEq, PartialOrd, Debug)]
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X);

impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { }

impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.0.partial_cmp(&other.0).unwrap()
    }
}

impl<X: PartialEq + PartialOrd> From<X> for ForceOrd<X> {
    fn from(x: X) -> ForceOrd<X> {
        ForceOrd(x)
    }
}

fn main() {
    let xs = vec![1.1f64, 3.5, 2.2];

    let max = xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap();

    println!("{:?}", max); // prints "ForceOrd(3.5)"
}

不幸的是,我恐怕这是你能做到的;你将无法实现:

impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X

能够参加期末考试

<f64>::from(xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap())

因为f64 不是这个箱子的本地。您可以在this very detailed blog entry by Niko Matsakis 中阅读有关此限制的更多信息,并查看this question in StackOverflow

【讨论】:

  • 我认为 OP 分别尝试了每个。问题是试图实现一个 trait,其中泛型类型具有当前 crate 中未声明的 trait bound。我不认为这是可能的。它可能在标准库中,因为那是原始特征所在的地方。
  • 我通过解决方案扩展了我的答案,以解决只有一个 impl 到位的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多