I have also tried to implement the From trait to allow construction of MyError from an instance of a Storage::Error:impl<S: Storage> From<S::Error> for MyError<S> { fn from(error: S::Error) -> MyError<S> { MyError::StorageProblem(error) }}(游乐场)但是编译失败: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 和 MyError 与我所看到的 S::Error 的类型不同.I don't understand why the compiler reckons this has already been implemented. The error message is telling me that there's already an implementation of From<MyError<_>> (which there is), but I'm not trying to implement that here - I'm trying to implement From<S::Error> and MyError is not the same type as S::Error from what I can see.我在这里是否遗漏了泛型的一些基础知识?Am I missing something fundamental to generics here?推荐答案这里的问题是有人可能会实现 Storage 以便您编写的 From 实现与impl 标准库中的 impl来自<T>for T(即任何东西都可以转换为自身).The problem here is someone may implement Storage so that the From impl you have written overlaps with the impl in the standard library of impl<T> From<T> for T (that is, anything can be converted to itself).具体来说,struct Tricky;impl Storage for Tricky { type Error = MyError<Tricky>;}(这里的设置意味着这实际上并不编译—MyError 是无限大的—但该错误与关于 impl 的推理无关/coherence/overlap,实际上对 MyError 的小改动可以让它在不改变基本问题的情况下编译,例如添加一个 Box 像 StorageProblem(Box<S::错误>),.)(The set-up here means this doesn't actually compile—MyError<Tricky> is infinitely large—but that error is unrelated to the reasoning about impls/coherence/overlap, and indeed small changes to MyError can make it compile without changing the fundamental problem, e.g. adding a Box like StorageProblem(Box<S::Error>),.)如果我们在你的实现中用 Tricky 代替 S,我们得到:If we substitute Tricky in place of S in your impl, we get:impl From<MyError<Tricky>> for MyError<Tricky> { ...}这个 impl 与 T == MyError 完全匹配自转换,因此编译器不会知道选择哪一个.Rust 编译器不会做出任意/随机的选择,而是避免了这种情况,因此由于这种风险,必须拒绝原始代码.This impl exactly matches the self-conversion one with T == MyError<Tricky>, and hence the compiler wouldn't know which one to choose. Instead of making an arbitrary/random choice, the Rust compiler avoids situations like this, and thus the original code must be rejected due to this risk.这种连贯性限制肯定很烦人,这也是 专业化 是一个备受期待的功能:本质上允许手动指示编译器如何处理重叠......至少,其中一个扩展允许这样做.This coherence restriction can definitely be annoying, and is one of reasons that specialisation is a much-anticipated feature: essentially allows manually instructing the compiler how to handle overlap... at least, one of the extensions to the current restricted form allows that. 这篇关于使用泛型类型时,“From"的实现如何存在冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
11-01 19:51