E0119 通用特征实现错误

E0119 error with generic trait implementation

我有一个枚举:

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`

String 不是 Into<i64> 的实现者,那么为什么会发生错误 E0119

TL;DR:where 个子句不算数。


问题的症结在于冲突检测目前仅基于模式:它不考虑where 个子句。

问题有 3 个方面:

  1. 决定 where 个子句是否允许重叠非常复杂,
  2. 决定哪个 where 子句比另一个更专业是相当复杂的(即将专业化),
  3. 允许否定推理意味着在库代码中添加特征实现现在是一个重大变化。

前两个纯粹是实现细节,但后者是语言设计方面的真正问题。想象一下:

  • 您的代码没有 Copy 绑定,
  • Rust 团队决定简化解析并添加 impl Into<i64> for &str.

突然之间,之前none的地方发生了冲突!您无法升级!

所以这里有一个真正的设计选择。您必须选择:

  • 能够编写不冲突的 impl(还),
  • 能够轻松升级您的依赖项。

你不能两者兼得。


注意:尝试在您选择的搜索引擎中输入 Rust explain <code>,然后看到 E0119。虽然这里用处不大。