已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新问题,以便editing this post可以用事实与引用来回答.
17天前关闭。
Improve this question
我有一个枚举,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`
--> 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_degrees
和to_radians
1.我将Angle::Degrees
和Angle::Radians
分成两个单独的结构体
如果1是不可能的,那么2和3中哪一个更可取?
2条答案
按热度按时间6rqinv9w1#
我想为这些实现
From
通过这段代码,你似乎希望
From::from
将以度为单位的值转换成以弧度为单位的值,反之亦然。*不可能,因为任何
From<T>
已经由T
的核心库实现;From
转换应该做的事情。因此,试图让编译器接受这一点是不可能的。提供的两个替代方案实际上是好的,并且不是互斥的。
是否为Angular (以度表示)和Angular (以弧度表示)定义独立的结构体取决于大小写。Rust API指南介绍了如何使用newtype模式通过防止混合不同的度量来防止严重的bug。另一方面,该类型已经做到了这一点。
laximzn52#
1确实是不可能的。Rust有一个全面的实现
impl<T> From<T> for T
,你不能覆盖它。此外,从语义上讲,你试图做的不是From
转换,而是改变某种类型的表示。我强烈推荐#2。它非常符合习惯,任何人看一眼就能知道这个方法会做什么(与你在例子中写的相反)。
你 * 可以 * 使用#3,但是这取决于你想如何设计你的代码。如果你已经开始使用枚举,它可能更适合你的问题,所以我建议你坚持使用它。但是如果你决定使用两个不同的结构体对你更好,那么#3仍然是好的。