2 回答

TA貢獻(xiàn)1863條經(jīng)驗 獲得超2個贊
這里的問題是有人可能會實現(xiàn),Storage
以便From
你寫的impl與標(biāo)準(zhǔn)庫中的impl重疊impl<T> From<T> for T
(也就是說,任何東西都可以轉(zhuǎn)換為自身)。
特別,
struct Tricky;impl Storage for Tricky { type Error = MyError<Tricky>;}
(這里的設(shè)置意味著這實際上不是編譯 - MyError<Tricky>
無限大 - 但該錯誤與關(guān)于impl
s / coherence /重疊的推理無關(guān),實際上小的改變MyError
可以使其編譯而不改變基本問題,例如添加一個Box
像StorageProblem(Box<S::Error>),
。)
如果我們用你的impl Tricky
代替S
,我們得到:
impl From<MyError<Tricky>> for MyError<Tricky> { ...}
這impl
與使用T
== 的自轉(zhuǎn)換完全匹配MyError<Tricky>
,因此編譯器不知道選擇哪一個。Rust編譯器避免了這樣的情況,而不是進(jìn)行任意/隨機(jī)選擇,因此必須拒絕原始代碼,因為存在這種風(fēng)險。
這種一致性限制肯定會令人煩惱,并且是專業(yè)化是一個備受期待的特性的原因之一:本質(zhì)上允許手動指示編譯器如何處理重疊......至少,當(dāng)前受限形式的擴(kuò)展之一允許這樣做。

TA貢獻(xiàn)1775條經(jīng)驗 獲得超11個贊
一致性問題的解決方法是使用Result::map_err
自己執(zhí)行轉(zhuǎn)換。然后,您可以使用末尾Result
帶有try!
或?
:
fn example<S: Storage>(s: S) -> Result<i32, MyError<S>> { s.do_a_thing().map_err(MyError::StorageProblem)?; Ok(42)}
當(dāng)存在具有相同底層的錯誤變體時,此解決方案也很有用Error
,例如,如果要分離“文件打開”和“文件讀取”錯誤,兩者都是io::Error
。
添加回答
舉報