- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现一个错误枚举,它可以包含与我们的特征之一相关联的错误,如下所示:
trait Storage {
type Error;
}
enum MyError<S: Storage> {
StorageProblem(S::Error),
}
我也尝试实现 From
允许构造 MyError
的特征来自 Storage::Error
的实例:
impl<S: Storage> From<S::Error> for MyError<S> {
fn from(error: S::Error) -> MyError<S> {
MyError::StorageProblem(error)
}
}
( playground )
但是编译失败:
error[E0119]: conflicting implementations of trait `std::convert::From<MyError<_>>` for type `MyError<_>`:
--> src/lib.rs:9:1
|
9 | impl<S: Storage> From<S::Error> for MyError<S> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> std::convert::From<T> for T;
我不明白为什么编译器认为这已经实现了。错误消息告诉我已经有一个 From<MyError<_>>
的实现。 (有),但我不是要在这里实现它 - 我正在尝试实现 From<S::Error>
和 MyError
与 S::Error
的类型不同据我所知。
我是否遗漏了一些泛型的基础知识?
最佳答案
这里的问题是有人可能会实现 Storage
这样 From
您编写的 impl 与 impl<T> From<T> for T
的标准库中的 impl 重叠(也就是说,任何东西都可以转化为自身)。
具体而言,
struct Tricky;
impl Storage for Tricky {
type Error = MyError<Tricky>;
}
(这里的设置意味着这实际上并没有编译——MyError<Tricky>
是无限大的——但是这个错误与关于 impl
s/coherence/overlap 的推理无关,而且实际上是对 MyError
的小改动。可以在不改 rebase 本问题的情况下编译它,例如添加一个 Box
像 StorageProblem(Box<S::Error>),
。)
如果我们替换 Tricky
代替 S
在您的暗示中,我们得到:
impl From<MyError<Tricky>> for MyError<Tricky> {
...
}
这impl
与 T
完全匹配的自转换== MyError<Tricky>
,因此编译器不知道选择哪一个。 Rust 编译器没有做出任意/随机选择,而是避免了这种情况,因此由于这种风险,必须拒绝原始代码。
这种一致性限制肯定很烦人,这也是 specialisation 的原因之一是一个备受期待的功能:本质上允许手动指示编译器如何处理重叠......至少,one of the extensions当前的限制形式允许这样做。
关于rust - 使用泛型时, `From` 的实现如何冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37347311/
我是一名优秀的程序员,十分优秀!