为什么两个不同特性的一揽子实现会发生冲突



假设我有这个代码:

pub trait A {}
pub trait B {}
pub trait SomeBehavior {
fn func() -> bool;
}

我想提供AB的一揽子实现,如下所示:

impl <T> SomeBehavior for T where T: A {
fn func() -> bool { true }
}
impl <T> SomeBehavior for T where T: B {
fn func() -> bool { false }
}

但这会产生以下错误:

error[E0119]: conflicting implementations of trait `SomeBehavior`
--> src/lib.rs:12:1
|
8  | impl <T> SomeBehavior for T where T: A {
| -------------------------------------- first implementation here
...
12 | impl <T> SomeBehavior for T where T: B {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

为什么编译器将具有不同特性的两个不同实现视为同一实现?

Rust有一个概念"特质一致性";这是一种思想,即对于类型和特质的任何组合,该特质最多应该有一个实现。这是指导Rust的";孤立规则";并且设计用于确保在下游板条箱中不会发生冲突的实现。

因此,上面两个一揽子实现的问题是一个类型可能同时实现AB。然后,对于该类型的SomeBehavior,将存在两个可能的实现。

struct MyType;
impl A for MyType;
impl B for MyType;
let t = MyType;
let _ = t.func(); // how to choose?

不幸的是,它在Rust中并没有得到特别好的记录;可能是因为其复杂性和争议性,这些年来规则发生了变化,未来可能还会再次发生变化。资源分散在博客文章、RFC和问题之间,但您可以在粉笔书(下一代特征求解器(的Coherence部分找到重要的部分。

未来可能会添加一些功能,允许这样或类似的功能:

  • 负impls(不稳定特性(
  • 专业化(RFC(
  • 板条箱级where子句(Niko Matsakis的博客文章(

最新更新