我遇到了相关类型的问题...我在 SO 上发现了类似的问题,比如这些:
但是虽然与我的情况非常接近,但它们并不相同......
所以我有一个与类型相关的特征:
trait Generator {
type Item;
fn next(&mut self) -> Self::Item;
}
还有另一个具有泛型方法的特征,它将第一个作为类型参数:
trait Iterator {
fn iterate<T>(&self, generator: T) -> T::Item
where T: Generator;
}
到目前为止一切正常。 现在我想创建一个结构并为其实现
Iterator
特征。
struct Baz<R> { // I want my struct to keep data of the same type as my associated type
data: Vec<R>, // So i make my struct generic
}
impl<R> Iterator for Baz<R>
{
fn iterate<T>(&self, generator: T) -> T::Item
where T: Generator<Item = R> // And specify associated type constraint for generic method
{
generator.next()
}
}
现在我收到错误:
error[E0271]: type mismatch resolving `<T as Generator>::Item == R`
--> src/main.rs:20:28
|
17 | impl<R> Iterator for Baz<R>
| - this type parameter
...
20 | where T: Generator<Item = R>
| ^^^^^^^^ expected associated type, found type parameter `R`
|
= note: expected associated type `<T as Generator>::Item`
found type parameter `R`
= note: you might be missing a type parameter or trait bound
note: the requirement `<T as Generator>::Item == R` appears on the `impl`'s method `iterate` but not on the corresponding trait's method
--> src/main.rs:9:8
|
8 | trait Iterator {
| -------- in this trait
9 | fn iterate<T>(&self, generator: T) -> T::Item
| ^^^^^^^ this trait's method doesn't have the requirement `<T as Generator>::Item == R`
我发现要修复它,我必须使我的迭代器特征通用并在特征定义中指定约束:
trait Iterator<R> {
fn iterate<T>(&self, generator: T) -> T::Item
where T: Generator<Item = R>;
}
并且还更新 impl 块:
impl<R> Iterator<R> for Baz<R>
{
...
}
但不幸的是,这个特征来自第三方库,所以我无法更新他们的源代码(更具体地说,它是来自 serde 库的 SeqAccess 特征)
所以我的问题是:在这种情况下有没有办法声明关联的类型约束而不向特征本身添加类型参数?
不,这不是你能做的事。考虑到接受
impl Iterator
的其他函数不会意识到这个新添加的约束,因此它们可以传递一个 Generator
,其 Item
类型与您的约束不匹配。 Iterator
中的函数签名对生成项的类型没有限制,因此该特征的消费者可以自由使用任何Generator
。