[英]Problem implementing a trait to multiple types
作为练习,我正在尝试创建一个温度单位库。
目前,以下代码无法编译,并且我不清楚错误消息。 问题似乎是类型冲突。
type Fahrenheit = f64;
type Celcius = f64;
type Kelvin = f64;
trait TemperatureUnit {
fn to_kelvin(&self) -> Kelvin;
}
impl TemperatureUnit for Fahrenheit {
fn to_kelvin(&self) -> Kelvin {
(*self + 459.67) * 5/9
}
}
impl TemperatureUnit for Celcius {
fn to_kelvin(&self) -> Kelvin {
*self + 273.15
}
}
impl TemperatureUnit for Kelvin {
fn to_kelvin(&self) -> Kelvin {
*self
}
}
错误:
error[E0119]: conflicting implementations of trait `TemperatureUnit` for type `f64`
--> src/lib.rs:18:1
|
12 | impl TemperatureUnit for Fahrenheit {
| ----------------------------------- first implementation here
...
18 | impl TemperatureUnit for Celcius {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `f64`
error[E0119]: conflicting implementations of trait `TemperatureUnit` for type `f64`
--> src/lib.rs:24:1
|
12 | impl TemperatureUnit for Fahrenheit {
| ----------------------------------- first implementation here
...
24 | impl TemperatureUnit for Kelvin {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `f64`
我是 Rust 的新手,所以也许这不是实现编译器强制类型安全单元转换的正确方法。
当你写type
时,你是在创建一个类型别名,而不是一个新类型。 例如,就像在 C++ 中使用typedef
一样。
type Fahrenheit = f64;
这字面意思是“当我说'华氏'时,假装我说的f64
”。 不是一种新的类型,不是一种独特的结构,字面上是一样的。 因此,您刚刚TemperatureUnit for f64
。
如果您想将f64
包装在您控制下的自定义类型中,您正在寻找newtype pattern 。
pub struct Fahrenheit(pub f64);
现在Fahrenheit
是一个独特的结构,恰好与f64
同构。 您可以使用Fahrenheit(x)
构造函数从f64
转到Fahrenheit
,也可以使用my_fahrenheit.0
投影返回。 如果您愿意,也可以命名投影。
pub struct Fahrenheit { pub float_repr: f64 };
Rust 几乎肯定会在内部将其编译为实际的f64
。 只有一个字段的结构通常没有开销。 但我们实际上可以用repr(transparent)
来保证这一点
#[repr(transparent)]
pub struct Fahrenheit(pub f64);
这保证了在运行时, Fahrenheit
和f64
具有相同的表示形式(即使在它们之间定义了transmute
的程度),而在编译时它们是不同的类型。
唯一需要决定的是您希望新类型实现哪些特征。 默认情况下,它不会从f64
继承任何内容,因此您可能会在声明之前有一个巨大的 derived derive(...)
子句,包括Eq
、 Ord
、 Clone
、 Copy
等(非详尽列表;您知道您的用例比我好)
这里的问题是type
只是一个类型的别名,它不会创建一个新的类型。 Rust 抱怨是因为这三个impl
块试图在同一类型上实现TemperatureUnit
三次。
相反,您应该声明新类型。 下面的示例使用struct
。
struct Fahrenheit(f64);
struct Celcius(f64);
struct Kelvin(f64);
trait TemperatureUnit {
fn to_kelvin(&self) -> Kelvin;
}
impl TemperatureUnit for Fahrenheit {
fn to_kelvin(&self) -> Kelvin {
Kelvin((self.0 + 459.67) * 5.0/9.0)
}
}
impl TemperatureUnit for Celcius {
fn to_kelvin(&self) -> Kelvin {
Kelvin(self.0 + 273.15)
}
}
impl TemperatureUnit for Kelvin {
fn to_kelvin(&self) -> Kelvin {
Kelvin(self.0)
}
}
fn main()
{
println!("Hey");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.