是否可以<T>在 Rust 中实现 From for T?

  • 本文关键字:实现 From for Rust 是否 rust
  • 更新时间 :
  • 英文 :


我有一个枚举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`
--> 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`.

据我所见,有三种选择:

  1. 我以某种方式向编译器澄清了这一点
  2. 我添加了两个单独的函数to_degreesto_radians
  3. 我将Angle::DegreesAngle::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仍然可以。

最新更新