我想有一个简单的类型转换,我认为代码应该看起来像这样:
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
trait是相关的,如果我实现From
,Into
将自动实现,但我不明白为什么Celsius
应该是泛型类型。
也许这段代码会更地道(至少这段代码可以编译):
fn danger_of_freezing<T: Into<Celsius>>(temp: T) -> bool {
let celsius: Celsius = temp.into();
celsius.0 < 0.0
}
但为什么第一个变体不起作用?
2条答案
按热度按时间5lhxktic1#
你是对的,任何实现
From
的东西都自动提供了一个自反的Into
实现,这意味着任何From
转换都可以使用.into()
,但是 * 相反的情况不是真的 *;一个类型可以实现Into
而不具有自反From
实现。使用
Into
(而不是From
)作为函数参数是惯用的,因此您应该像上一个代码片段那样在函数体内使用.into()
。busg9geu2#
如果你的问题是为什么
Celsius::from(temp)
给出一个错误.在您的代码中,
Celsius::from
有两个方法实现Celsius::from(temp: Fahrenheit)
您提供的Celsius::from(temp: Celsius)
是通用的,因为From
是自反的。所以这是有效的:
而任何其他类型都不是,例如泛型类型
T
。