[英]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.