我遇到了一个与相关类型有关的问题.我在So上发现了类似的问题,比如下面这些问题:

但是,虽然与我的案件非常接近,但它们并不相同……

因此,我有一个相关类型的特征:

trait Generator {
    type Item;
    fn next(&mut self) -> Self::Item;
}

泛型方法的另一个特征,它将第一个作为类型参数:

trait Iterator {
    fn iterate<T>(&self, generator: T) -> T::Item
        where T: Generator;
}

到目前为止一切都还好. 现在我想创建一个 struct ,并为它实现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`

我想要修复它,我必须使我的Iterator特征成为泛型,并在特征定义中指定约束:

trait Iterator<R> {
    fn iterate<T>(&self, generator: T) -> T::Item
        where T: Generator<Item = R>;
}

还可以更新Iml块:

impl<R> Iterator<R> for Baz<R>
{
    ...
}

但不幸的是,这个特征来自第三方库,所以我不能更新他们的源代码(更确切地说,这是来自serde库的SeqAccess特征)

所以我的问题是:在这种情况下,有没有办法声明关联的类型约束,而不向特征本身添加类型参数?

推荐答案

不,这不是你能做的事.考虑到接受impl Iterator的其他函数不会知道这个新添加的约束,因此它们可以传递Item类型与您的约束不匹配的Generator.Iterator中函数的签名没有对生成的项的类型施加任何限制,因此特征的消费者完全可以自由地使用任何Generator.

Rust相关问答推荐

关于Rust 中回归的逻辑

通过解引用将值移出Box(以及它被脱糖到什么地方)?

闭包不会发送,即使它只捕获发送变量

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

对于rustc编译的RISC-V32IM二进制文件,llvm objdump没有输出

应为关联类型,找到类型参数

减少指示ProgressBar在Rust中的开销

在为第三方 struct 实现第三方特征时避免包装器的任何方法

为什么我们有两种方法来包含 serde_derive?

Option<&T> 如何实现复制

如何基于常量在Rust中跳过一个测试

Rust中的位移操作对范围有什么影响?

如何判断服务器是否正确接收数据

特征中定义的类型与一般定义的类型之间的区别

如何展平以下嵌套的 if let 和 if 语句?

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

在 Rust 中退出进程

在 Traits 函数中设置生命周期的问题

通用类型,不同于输入类型,作为函数的返回值

为什么 Rust 标准库同时为 Thing 和 &Thing 实现特征?