我有一个枚举Angle
,它有两个变体Degrees
和Radians
。我想为这些实现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`
--> srclib.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`.
据我所见,有三种选择:
- 我以某种方式向编译器澄清了这一点
- 我添加了两个单独的函数
to_degrees
和to_radians
- 我将
Angle::Degrees
和Angle::Radians
分离为两个独立的结构
如果1不可能,2和3中哪个更可取?
我想为这些实现
From
根据该代码,您似乎希望From::from
将度数值转换为弧度值,反之亦然。然而,这不仅仅是:
-
不可能,因为任何
From<T>
都已经由T
的核心库实现 - 而且不直观,因为这远远不是
From
转换应该做的
因此,试图让编译器接受这一点是不可能的。提供的两种备选方案实际上是好的,并不相互排斥。
是否为角度(以度为单位(和角度(以弧度为单位(定义独立结构取决于大小写。值得一提的是,Rust API指南显示了如何使用newtype模式来防止混合不同的措施来防止严重的错误。另一方面,这种类型已经做到了。
#1确实是不可能的。Rust有一个一揽子实现impl<T> From<T> for T
,你不能覆盖它。此外,从语义上讲,你试图做的不是From
转换,而是改变某种类型的表示。
我强烈推荐#2。它非常地道,任何人都可以在看一眼后就知道这些方法会做什么(与您在示例中所写的相反(。
可以做#3,但如何设计代码取决于您。如果你已经开始使用枚举,它可能更适合你的问题,所以我建议你坚持使用它。但如果你决定使用两个不同的结构对你更好,那么#3仍然可以。