gpt4 book ai didi

rust - 使用泛型类型时, `From`的实现有何冲突?

转载 作者:行者123 更新时间:2023-12-03 11:49:18 31 4
gpt4 key购买 nike

我正在尝试实现一个错误枚举,该枚举可能包含与我们的特征之一相关的错误,如下所示:

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>,而 MyErrorS::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> {
...
}

implT == MyError<Tricky>完全匹配自我转换,因此编译器将不知道该选择哪一个。 Rust编译器没有做出任何选择/随机选择,而是避免了这种情况,因此由于这种风险,原始代码必须被拒绝。

这种连贯性限制肯定会很烦人,并且是 specialisation是一个备受期待的功能的原因之一:本质上允许手动指示编译器如何处理重叠……至少, one of the extensions以当前的受限形式可以做到这一点。

关于rust - 使用泛型类型时, `From`的实现有何冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60932631/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com