rust - 为带约束的结构实现 From/Into

标签 rust traits

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

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

但是,我无法得到 Into trait 实现来编译错误:

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

最佳答案

你不能同时拥有 FromInto为单一类型实现,即你不能 impl From<ForceOrd<X>> for X如果你也impl Into<X> for ForceOrd<X> .你也只需要一个。作为 Into 的文档和 From 两种状态:

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不是这个 crate 的本地。您可以在 this very detailed blog entry by Niko Matsakis 中阅读有关此限制的更多信息并查看 this question in StackOverflow .

关于rust - 为带约束的结构实现 From/Into,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39939664/

相关文章:

generics - 如何在成功时返回用户指定的类型或在失败时返回 String?

rust - 我对静态特征界限的理解是否正确?

c++ - 是否有特征或任何约定来检查范围或 `view_facade` 是否拥有事物? (例如 getlines)

parsing - 是否可以为任意类型派生一个解析相应调试格式的解析器?

multithreading - 如何控制 Rust 中 2 个不同线程的打印顺序

Scala 特征和隐式转换混淆

php - 级联更新列关系 Laravel 5.6

scala - 在 Scala 中泛化构造函数

rust - 如何避免借用在不使用克隆的情况下移入闭包的值?

rust - 如何声明和实现一个跟踪结构集合的结构?