[英]Why are implementations of Iterator<Item = T> and Iterator<Item = &T> conflicting?
此代碼無法編譯:
pub trait ToVec<T> {
fn to_vec(self) -> Vec<T>;
}
impl<I, T> ToVec<T> for I
where
I: Iterator<Item = T>,
{
fn to_vec(self) -> Vec<T> {
self.collect()
}
}
impl<'a, I, T> ToVec<T> for I
where
I: Iterator<Item = &'a T>,
T: Clone,
{
fn to_vec(self) -> Vec<T> {
self.cloned().collect()
}
}
錯誤:
error[E0119]: conflicting implementations of trait `ToVec<_>`:
--> src/lib.rs:14:1
|
5 | / impl<I, T> ToVec<T> for I
6 | | where
7 | | I: Iterator<Item = T>,
8 | | {
... |
11 | | }
12 | | }
| |_- first implementation here
13 |
14 | / impl<'a, I, T> ToVec<T> for I
15 | | where
16 | | I: Iterator<Item = &'a T>,
17 | | T: Clone,
... |
21 | | }
22 | | }
| |_^ conflicting implementation
據我了解,當給定類型I
實現Iterator
時, I::Item
只能具有一種特定類型,因此它不能同時滿足兩種實現。
這是編譯器的限制還是我的推理不正確? 如果是這樣,請提供一個同時滿足這兩個 impls 的示例。
我相信這是問題 #20400, Can't write non-overlapping Blank impls that involved associated type bindings 。 總而言之, impl
實際上是不重疊的,但是教編譯器認識到這會引入一種否定推理形式,這與 trait solver 當前的工作方式有很大不同。 編寫了一個 RFC來解決這個問題,但部分原因是由於對兩種類型重疊的含義不明確,所以推遲了。
這個問題似乎最終會被重新審視和修復,但可能需要一些時間。
同時,您可能會編寫一個基於向Trait
添加類型參數的解決方法,如我對Can I Avoid eager ambiguity resolution for trait implementations with generics? (盡管在您的情況下,由於您的impl
s實際上從不重疊,因此您不必使用 turbofish 來選擇impl
;編譯器應該始終弄清楚。)
粗略地說,帶有Item = &X
的迭代器將同時滿足:
T == &X
=> 可能導致Vec<&X>
T == X
=> 的第二個可能導致Vec<X>
也許專業化(每晚)會有所幫助,但我不確定。
泛型類型參數T
表示的類型集是泛型類型參數&T
表示的類型集的超集。 它們並不脫節。 &T
中的所有內容也在T
中,因此存在沖突的實現消息。
最小的例子:
trait Trait {}
impl<T> Trait for T {}
impl<T> Trait for &T {} // compile error
拋出:
error[E0119]: conflicting implementations of trait `Trait` for type `&_`:
--> src/lib.rs:5:1
|
3 | impl<T> Trait for T {}
| ------------------- first implementation here
4 |
5 | impl<T> Trait for &T {} // compile error
| ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.