亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用泛型類型時,如何實現“From”的沖突?

使用泛型類型時,如何實現“From”的沖突?

我正在嘗試實現一個錯誤枚舉,它可能包含與我們的某個特征相關的錯誤,如下所示: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)     }}但是這無法編譯: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我所看到的類型不同。我是否遺漏了仿制藥的基本內容?使用泛型類型時,如何實現“From”的沖突?
查看完整描述

2 回答

?
小唯快跑啊

TA貢獻1863條經驗 獲得超2個贊

這里的問題是有人可能會實現,Storage以便From你寫的impl與標準庫中的impl重疊impl<T> From<T> for T(也就是說,任何東西都可以轉換為自身)。

特別,

struct Tricky;impl Storage for Tricky {
    type Error = MyError<Tricky>;}

(這里的設置意味著這實際上不是編譯 - MyError<Tricky>無限大 - 但該錯誤與關于impls / coherence /重疊的推理無關,實際上小的改變MyError可以使其編譯而不改變基本問題,例如添加一個BoxStorageProblem(Box<S::Error>),。)

如果我們用你的impl Tricky代替S,我們得到:

impl From<MyError<Tricky>> for MyError<Tricky> {
    ...}

impl與使用T== 的自轉換完全匹配MyError<Tricky>,因此編譯器不知道選擇哪一個。Rust編譯器避免了這樣的情況,而不是進行任意/隨機選擇,因此必須拒絕原始代碼,因為存在這種風險。

這種一致性限制肯定會令人煩惱,并且是專業化是一個備受期待的特性的原因之一:本質上允許手動指示編譯器如何處理重疊......至少,當前受限形式的擴展之一允許這樣做。


查看完整回答
反對 回復 2019-08-28
?
繁星淼淼

TA貢獻1775條經驗 獲得超11個贊

一致性問題的解決方法是使用Result::map_err自己執行轉換。然后,您可以使用末尾Result帶有try!?

fn example<S: Storage>(s: S) -> Result<i32, MyError<S>> {
    s.do_a_thing().map_err(MyError::StorageProblem)?;
    Ok(42)}

當存在具有相同底層的錯誤變體時,此解決方案也很有用Error,例如,如果要分離“文件打開”和“文件讀取”錯誤,兩者都是io::Error。


查看完整回答
反對 回復 2019-08-28
  • 2 回答
  • 0 關注
  • 611 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號