2017-03-14 30 views
4

E0119錯誤我有一個枚舉:與一般的特質實施

enum Field { 
    Str(String), 
    Integer(i64), 
} 

我想做的事:

impl From<String> for Field { 
    fn from(s: String) -> Field { 
     Field::Str(s) 
    } 
} 

impl<I> From<I> for Field where I: Into<i64> + Copy { 
    fn from(i: I) -> Field { 
     Field::Integer(Into::<i64>::into(i)) 
    } 
} 

上面這段代碼有錯誤:

error[E0119]: conflicting implementations of trait 
`std::convert::From<std::string::String>` for type `Field`: 
--> <anon>:12:5 
    | 
6 |   impl From<String> for Field { 
    | ________- starting here... 
7 | |  fn from(s: String) -> Field { 
8 | |   Field::Str(s) 
9 | |  } 
10 | |  } 
    | |_____- ...ending here: first implementation here 
11 | 
12 |  impl<I> From<I> for Field where I: Into<i64> + Copy { 
    | _____^ starting here... 
13 | |  fn from(i: I) -> Field { 
14 | |   Field::Integer(Into::<i64>::into(i)) 
15 | |  } 
16 | |  } 
    | |_____^ ...ending here: conflicting implementation for `Field` 

StringInto<i64>的實現者,爲什麼錯誤E0119發生?

+0

注意:'Copy'綁定在這裏是多餘的。 –

+0

*'String'不是'Into '的實現者* - 現在不是**,它不是。 – Shepmaster

回答

3

TL; DR:where條款不計算在內。


問題的癥結是,衝突檢測是基於目前僅模式:它不佔where條款。

問題是3倍:

  1. 決定where條款是否允許重疊或不是相當複雜的,
  2. 決定哪些where子句是更專門比另一個是相當複雜的(即將到來的專門化),
  3. 允許否定推理意味着在庫代碼中添加trait實現現在是一個重大改變。

前兩個是純粹的實現細節,但後者是語言設計方面的真正關注點。想象一下:

  • 您的代碼不具備Copy約束,
  • 鏽團隊決定讓分析更容易,並添加impl Into<i64> for &str

突然間,之間沒有任何衝突!你不能升級!

所以這裏有一個真正的設計選擇。你必須選擇之間:

  • 能夠編寫不衝突(還)IMPL,
  • 能夠無痛升級你的依賴。

你不能同時擁有兩者。


注:嘗試在您選擇的搜索引擎中鍵入Rust explain <code>,不料E0119。雖然在這裏沒有幫助。

+0

或'cargo --explain e0119'或'rustc --explain e0119' – Shepmaster