我有一个枚举:

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: 100 clauses don't count.


问题的关键在于,冲突检测目前是solely pattern based条:它没有解释where条.

问题有三个方面:

  1. 决定where个条款是否允许重叠相当复杂,
  2. 决定哪一个where分句比另一个更专业是相当复杂的(即将到来的专业化),
  3. 允许negative reasoning意味着在库代码中添加一个trait实现现在是一个突破性的改变.

前两个纯粹是实现细节,而后一个是语言设计方面真正需要考虑的问题.想象一下:

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

突然之间,发生了一场以前从未发生过的冲突!你不能升级!

所以这里有一个真正的设计 Select .你必须在以下两者之间做出 Select :

  • 能够编写不冲突的impl(目前),
  • 能够毫不费力地升级依赖项.

你不能两者兼得.


Note: try typing 101 in your search engine of choice, and behold 100. Although it's not that helpful here.

Rust相关问答推荐

如何从polars DataFrame中获取一个列作为Option String?<>

无法在线程之间安全地发送future (&Q;)&错误

Rust:跨多个线程使用hashmap Arc和rwlock

我如何在Rust中使用传递依赖中的特征?

为什么BitVec缺少Serialize trait?

了解Rust';s特征对象和不同函数签名中的生存期注释

Tokio';s io::用Cursor拆分<;Vec<;u8>>;赢得';t get the full writted data

在什么情况下 `..._or()` 比 `..._or_else(|| {})` 更好,为什么?

为什么某些类型参数仅在特征边界中使用的代码在没有 PhantomData 的情况下进行编译?

需要一个有序向量来进行 struct 初始化

unwrap 选项类型出现错误:无法移出共享引用后面的*foo

更新 rust ndarray 中矩阵的一行

Rust 程序中的内存泄漏

从光标位置旋转精灵

如何递归传递闭包作为参数?

如果不满足条件,如何在 Rust 中引发错误

LinkedList::drain_filter::drop 中 DropGuard 的作用是什么?

我如何将特征作为 struct 的拥有字段?

为什么 no_std crate 可以依赖于使用 std 的 crate?

具有生命周期和以后引用的可变方法