是否可以< T>在Rust中实现From for T?[已关闭]

ergxz8rk  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(224)

已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新问题,以便editing this post可以用事实与引用来回答.

17天前关闭。
Improve this question
我有一个枚举,Angle,它有两个变量,DegreesRadians。我想为它们实现From,但它不允许:

enum Angle {
    Degrees(f64),
    Radians(f64)
}

impl From<Angle> for Angle {
    fn from(value: Angle) -> Self {
        match value {
            Angle::Degrees(deg) => Angle::Radians(deg / 180.0 * PI),
            Angle::Radians(rad) => Angle::Degrees(rad / PI * 180.0)
        }
    }
}

其抛出了

error[E0119]: conflicting implementations of trait `std::convert::From<Angle>` for type `Angle`
  --> src\lib.rs:45:1
   |
45 | impl From<Angle> for Angle {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T> From<T> for T;

Some errors have detailed explanations: E0119, E0412, E0425.
For more information about an error, try `rustc --explain E0119`.

在我看来,有三种选择:
1.我以某种方式向编译器澄清了这一点
1.我添加了两个单独的函数to_degreesto_radians
1.我将Angle::DegreesAngle::Radians分成两个单独的结构体
如果1是不可能的,那么2和3中哪一个更可取?

6rqinv9w

6rqinv9w1#

我想为这些实现From
通过这段代码,你似乎希望From::from将以度为单位的值转换成以弧度为单位的值,反之亦然。

*不可能,因为任何From<T>已经由T的核心库实现;

  • 而且不直观,因为这远远不是From转换应该做的事情。

因此,试图让编译器接受这一点是不可能的。提供的两个替代方案实际上是好的,并且不是互斥的。
是否为Angular (以度表示)和Angular (以弧度表示)定义独立的结构体取决于大小写。Rust API指南介绍了如何使用newtype模式通过防止混合不同的度量来防止严重的bug。另一方面,该类型已经做到了这一点。

laximzn5

laximzn52#

1确实是不可能的。Rust有一个全面的实现impl<T> From<T> for T,你不能覆盖它。此外,从语义上讲,你试图做的不是From转换,而是改变某种类型的表示。

我强烈推荐#2。它非常符合习惯,任何人看一眼就能知道这个方法会做什么(与你在例子中写的相反)。
你 * 可以 * 使用#3,但是这取决于你想如何设计你的代码。如果你已经开始使用枚举,它可能更适合你的问题,所以我建议你坚持使用它。但是如果你决定使用两个不同的结构体对你更好,那么#3仍然是好的。

相关问题