我想要一个简单的类型转换,我认为代码应该如下所示:
struct Celsius(f64);
struct Fahrenheit(f64);
impl From<Celsius> for Fahrenheit {
fn from(c: Celsius) -> Self {
Fahrenheit(c.0 * 9. / 5. + 32.)
}
}
impl From<Fahrenheit> for Celsius {
fn from(f: Fahrenheit) -> Self {
Celsius((f.0 - 32.) * 5. / 9.)
}
}
fn danger_of_freezing<T: Into<Celsius>>(temp: T) -> bool {
let celsius = Celsius::from(temp);
celsius.0 < 0.0
}
fn main() {
danger_of_freezing(Celsius(20.0));
danger_of_freezing(Fahrenheit(68.0));
}
但是编译器给了我这个:
error[E0277]: the trait bound `Celsius: From<T>` is not satisfied
--> src\main.rs:17:33
|
17 | let celsius = Celsius::from(temp);
| ------------- ^^^^ the trait `From<T>` is not implemented for `Celsius`
| |
| required by a bound introduced by this call
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
16 | fn danger_of_freezing<T: Into<Celsius>>(temp: T) -> bool where Celsius: From<T> {
| ++++++++++++++++++++++
我不明白我的代码问题出在哪里。我知道
From
和 Into
特征是相关的,如果我实现 From
,Into
将自动实现,但我不明白为什么 Celsius
应该是泛型类型。
也许这段代码会更惯用(至少这段代码可以编译):
fn danger_of_freezing<T: Into<Celsius>>(temp: T) -> bool {
let celsius: Celsius = temp.into();
celsius.0 < 0.0
}
但是为什么第一个变体不起作用?
你是对的,任何实现
From
的东西都会自动提供自反 Into
实现,这意味着任何 From
转换都可以使用 .into()
,但相反则不然;类型可以实现 Into
但没有自反 From
实现。
使用
Into
(而不是 From
)作为函数参数是惯用的,因此您应该像上一个代码片段一样在函数体内使用 .into()
。
如果您的问题是为什么
Celsius::from(temp)
给出错误...
在您的代码中,恰好有两个方法实现
Celsius::from
Celsius::from(temp: Fahrenheit)
您提供的Celsius::from(temp: Celsius)
这是通用的,因为 From
是自反的。所以这是有效的:
Celsius::from(Celsius(1.));
Celsius::from(Fahrenheit(1.));
任何其他类型都不是,例如泛型类型
T
。