我试图编译此代码(Playground):
trait Family<'a> {
type Out;
}
struct U32Family;
impl<'a> Family<'a> for U32Family {
type Out = u32;
}
trait Iterator {
type Item;
fn next<'s>(&'s mut self) -> <Self::Item as Family<'s>>::Out
where
Self::Item: Family<'s>;
}
struct Foo;
impl Iterator for Foo {
type Item = U32Family;
fn next<'s>(&'s mut self) -> <Self::Item as Family<'s>>::Out
where
Self::Item: Family<'s>,
{
0u32 // <-- in real code, this is somehow calculated
}
}
但是可悲的是,它导致了这个错误:
error[E0308]: mismatched types
--> src/main.rs:28:9
|
24 | fn next<'s>(&'s mut self) -> <Self::Item as Family<'s>>::Out
| ------------------------------- expected `<U32Family as Family<'s>>::Out` because of return type
...
28 | 0u32
| ^^^^ expected associated type, found u32
|
= note: expected type `<U32Family as Family<'s>>::Out`
found type `u32`
我真的不明白为什么。显然,在此代码段中,
<U32Family as Family<'s>>::Out
正是u32
。但是Rust似乎认为并不总是一样。 为什么?以及如何使它编译? 一些注意事项:
type Out: for<'a> Family<'a>;
。因此,这不是对我有效的解决方法。 Family
的生命周期参数,则一切正常。 Family<'s>
替换为Family<'static>
,则一切正常。 编辑:我可以通过添加以下方法来解决此问题:
impl U32Family {
fn from<'a>(v: u32) -> <Self as Family<'a>>::Out {
v
}
}
然后,我可以在
Self::Item::from(0u32)
主体中说next()
。 (Playground)我认为很清楚为什么
next()
中的错误消失了:U32Family::from
始终将u32
作为参数。硬编码。永不改变。关于此解决方法的更大问题是:为什么from()
方法可以正常编译?因此,在from()
中,编译器以某种方式知道<Self as Family<'a>>::Out
始终是u32
,但是如果我在next()
中尝试相同的操作,则以某种方式,编译器将无法理解<Self::Item as Family<'s>>::Out
是u32
。现在我更加困惑了。EDIT2 :首先,我怀疑特化是问题所在。例如,您可以编写:
impl Family<'static> for U32Family {
type Out = char;
}
那么,当然,对于任何
u32
,<Self::Item as Family<'s>>::Out
并不总是与's
相同,那么编译器将是正确的。但是,我认为这不是问题。首先,暗示可以是专门的need to be marked with the
default
keyword。我没有这样做,所以我应该能够假定关联的类型实际上是u32
(the RFC talks about something very similar)。但此外,基于生存期is not allowed的特化。因此,到目前为止,我倾向于认为这是编译器错误。但我想再得到一个答案!
最佳答案
我认为问题在于,对于所有<Self::Item as Family<'s>>::Out
来说u32
是's
是“巧合”。编译器可以针对所需的任何's
证明这一点,但它甚至无法表达出对所有's
都是正确的概念。
您找到的解决方法是正确的方法:在U32Family
中添加一个方法,该方法可将u32
转换为<Self as Family<'a>>::Out
。该方法的主体完全在'a
的范围内,因此编译器可以证明该'a
的转换是类型正确的,因此该方法是类型正确的。然后,在调用现场,您要告诉编译器使用其有关该方法的知识。
关于rust - “Expected associated type, found ` u32 `”,在将参数的生存期用作受约束位置的特征参数时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51638863/