Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 为什么迭代器和迭代器的实现相互冲突?_Generics_Rust_Polymorphism_Traits_Parametric Polymorphism - Fatal编程技术网

Generics 为什么迭代器和迭代器的实现相互冲突?

Generics 为什么迭代器和迭代器的实现相互冲突?,generics,rust,polymorphism,traits,parametric-polymorphism,Generics,Rust,Polymorphism,Traits,Parametric Polymorphism,此代码无法编译: 托维茨酒店{ fn至_vecself->Vec; } 为我祈祷 哪里 I:迭代器, { fn至_vecself->Vec{ 自付 } } impl, T:克隆, { fn至_vecself->Vec{ self.clone.collect } } 错误: 错误[E0119]:trait'ToVec'的冲突实现: ->src/lib.rs:14:1 | 5 |/impl ToVec for I 6 | |在哪里 7 | | I:迭代器, 8 | | { ... | 11 |

此代码无法编译:

托维茨酒店{ fn至_vecself->Vec; } 为我祈祷 哪里 I:迭代器, { fn至_vecself->Vec{ 自付 } } impl, T:克隆, { fn至_vecself->Vec{ self.clone.collect } } 错误:

错误[E0119]:trait'ToVec'的冲突实现: ->src/lib.rs:14:1 | 5 |/impl ToVec for I 6 | |在哪里 7 | | I:迭代器, 8 | | { ... | 11 | | } 12 | | } ||(uu)-这里的第一个实现 13 | 14 |/impl, 17 | | T:克隆, ... | 21 | | } 22 | | } || ^冲突的实现 据我所知,当一个给定的类型实现迭代器时,I::Item只能有一个特定的类型,所以它不能同时满足两个实现


这是编译器的限制还是我的推理不正确?如果是这样,请提供一个同时满足两个impl的示例。

粗略地说,Item=&X的迭代器将同时满足以下两个条件:

第一个带有T==&X=>的可能会导致Vec 第二个T==X=>可能会导致Vec
也许每晚专门化会有所帮助,但我不确定。

粗略地说,Item=&X的迭代器可以同时满足以下两个条件:

第一个带有T==&X=>的可能会导致Vec 第二个T==X=>可能会导致Vec
每晚的专门化可能会有所帮助,但我不确定。

泛型类型参数T表示的类型集是泛型类型参数&T表示的类型集的超集。它们不是不相交的。&T中的所有内容也都在T中,因此存在冲突的实现消息

最简单的例子:

性状{} T{}的impl特征 &T{}//的impl Trait编译错误 抛出:

错误[E0119]:类型“%&”的trait`trait`的实现冲突: ->src/lib.rs:5:1 | T{}的3 | impl性状 |-------这里的第一个实现 4 | 5 | impl Trait for&T{}//编译错误 |^^^^^^^^^^^^^^^^^^^^^^^^^^^的冲突实现`&_`
泛型类型参数T表示的类型集是泛型类型参数&T表示的类型集的超集。它们不是不相交的。&T中的所有内容也都在T中,因此存在冲突的实现消息

最简单的例子:

性状{} T{}的impl特征 &T{}//的impl Trait编译错误 抛出:

错误[E0119]:类型“%&”的trait`trait`的实现冲突: ->src/lib.rs:5:1 | T{}的3 | impl性状 |-------这里的第一个实现 4 | 5 | impl Trait for&T{}//编译错误 |^^^^^^^^^^^^^^^^^^^^^^^^^^^的冲突实现`&_`
我相信这是第20400期。总而言之,IMPL实际上是不重叠的,但教编译器认识到这一点会引入一种否定推理,这与特质解算器目前的工作方式有很大的不同。是为了解决这个问题而写的,但推迟的部分原因是对两种类型重叠意味着什么的含糊不清

似乎这个问题最终会被重新讨论和解决,但这可能需要一些时间


同时,您可能会编写一个基于向Trait添加类型参数的解决方案,就像我对的回答一样,尽管在您的案例中,由于您的impl实际上从未重叠,因此您永远不必使用turbofish来选择impl;编译器应该总是能找到答案。

我认为这是20400问题。总而言之,IMPL实际上是不重叠的,但教编译器认识到这一点会引入一种否定推理,这与特质解算器目前的工作方式有很大的不同。是为了解决这个问题而写的,但推迟的部分原因是对两种类型重叠意味着什么的含糊不清

似乎这个问题最终会被重新讨论和解决,但这可能需要一些时间


同时,您可能会编写一个基于向Trait添加类型参数的解决方案,就像我对的回答一样,尽管在您的案例中,由于您的impl实际上从未重叠,因此您永远不必使用turbofish来选择impl;编译器应该总是能找到答案。

我觉得这是允许的。例如,这段代码是编译的,这不应该是冲突,因为ToVec和ToVec也是不同的特性。当然有可能我遗漏了一些东西。@apilat它们是不同的特征,但也不是超集over&T并不意味着i32是超集over&i32I认为这是允许的。例如,这段代码是编译的,这不应该是冲突,因为ToVec和ToVec也是不同的特性。当然有可能我遗漏了一些东西。@apilat它们是不同的特征,但是T是超集over&T并不意味着i32是超集over&i32。在您的示例中,不同之处在于Trait没有泛型类型参数。如果我添加一个,代码是@apilat。谢谢,这有助于e
解释为什么T是&T的超集,但这并不是我要反驳的。为了清楚起见,考虑使用P和Q。在我的理解中,我们可以有重叠实现的唯一方法是如果P==Q,但是O:Other+Other是不可能的,因为P!=&P、 因此,我们不能通过矛盾来实现重叠。我的推理正确吗?只要P==&QNo,就会有重叠的实现,当P==&Q时,就会得到impl Trait for&Q{},这与示例中的不同之处在于Trait没有泛型类型参数。如果我加上一个,代码是。@apilat.谢谢,这有助于解释为什么T是&T的超集,但这不是我要反驳的。为了清楚起见,考虑使用P和Q。在我的理解中,我们可以有重叠实现的唯一方法是如果P==Q,但是O:Other+Other是不可能的,因为P!=&P、 因此,我们不能通过矛盾来实现重叠。我的推理正确吗?只要P==&QNo,就会有重叠的实现,当P==&Q时,就会得到impl Trait for&Q{}其中。中提到了相同的问题,但解决方法似乎不适用于您这样的案例。中提到了相同的问题,但解决方法似乎不适用于您这样的案例。在20400期中,impl显然没有重叠,因为给出的示例对每个IML使用了不同的具体类型,例如u8和u16。然而,在OP的例子中,因为他使用T和&'a T,其中T在两个impl中都是不同的泛型类型参数,所以我们可以为第一个T选择&'a i32,为第二个T选择i32,然后我们将有&'a i32==&'a i32,这是一个重叠。即使20400问题已经解决,我也不相信OP的例子会在那时编译。@pretzelhammer如果你在第一个impl中选择T=&a i32,在第二个impl中选择T=i32,那么这两个impl将实现ToVecOh,我明白了!谢谢你的解释!谢谢你的详细解释。在本案例中是否应用了链接答案中的技巧。在20400版中,impl显然没有重叠,因为给出的示例对每个IML使用了不同的混凝土类型,例如u8和u16。然而,在OP的例子中,因为他使用T和&'a T,其中T在两个impl中都是不同的泛型类型参数,所以我们可以为第一个T选择&'a i32,为第二个T选择i32,然后我们将有&'a i32==&'a i32,这是一个重叠。即使20400问题已经解决,我也不相信OP的例子会在那时编译。@pretzelhammer如果你在第一个impl中选择T=&a i32,在第二个impl中选择T=i32,那么这两个impl将实现ToVecOh,我明白了!谢谢你的解释!谢谢你的详细解释。链接答案中的技巧是否适用于本例。