我有一个枚举:
enum Field {
Str(String),
Integer(i64),
}
我想这样做:
impl From<String> for Field {
fn from(s: String) -> Field {
Field::Str(s)
}
}
impl<I> From<I> for Field where I: Into<i64> + Copy {
fn from(i: I) -> Field {
Field::Integer(Into::<i64>::into(i))
}
}
上面的代码有错误:
error[E0119]: conflicting implementations of trait
`std::convert::From<std::string::String>` for type `Field`:
--> <anon>:12:5
|
6 | impl From<String> for Field {
| ________- starting here...
7 | | fn from(s: String) -> Field {
8 | | Field::Str(s)
9 | | }
10 | | }
| |_____- ...ending here: first implementation here
11 |
12 | impl<I> From<I> for Field where I: Into<i64> + Copy {
| _____^ starting here...
13 | | fn from(i: I) -> Field {
14 | | Field::Integer(Into::<i64>::into(i))
15 | | }
16 | | }
| |_____^ ...ending here: conflicting implementation for `Field`
String
不是Into<i64>
的实施者,为什么错误E0119
会发生?
答案 0 :(得分:4)
TL; DR:where
条款不计算在内。
问题的关键在于冲突检测目前只是基于模式的:它不会考虑where
条款。
问题是3倍:
where
子句是否允许重叠是非常复杂的,where
子句比另一个更专业是非常复杂的(即将推出的专业化),前两个是纯粹的实现细节,但后者在语言设计方面是一个真正的问题。想象一下:
Copy
绑定,impl Into<i64> for &str
。突然间,发生了一场之前没有冲突的冲突!你无法升级!
所以这里有一个真正的设计选择。你必须在:
之间选择你不能同时拥有两者。
注意:尝试在您选择的搜索引擎中输入Rust explain <code>
,然后看E0119。虽然在这里没有那么有用。