Trait 实现了 Iterator,但不能使用将我的 trait 实现为 Iterator 的结构

Ror*_*ory 4 traits rust

我有一个特征,我想说的是,如果一个结构实现了这个特征,那么它也可以作为一个Iterator. 但是,在尝试将结构用作迭代器时出现编译器错误。

我正在编写一个库来从许多不同的文件格式中读取相同类型的数据。我想创建一个通用的“阅读器”特征,它将返回正确的 Rust 对象。我想说每个读者都可以作为一个迭代器操作,产生那个对象。

这是代码

/// A generic trait for reading u32s
trait MyReader {
    fn get_next(&mut self) -> Option<u32>;
}

/// Which means we should be able to iterate over the reader, yielding u32s
impl Iterator for MyReader {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        self.get_next()
    }
}

/// Example of a 'reader'
struct MyVec {
    buffer: Vec<u32>,
}

/// This can act as a reader
impl MyReader for MyVec {
    fn get_next(&mut self) -> Option<u32> {
        self.buffer.pop()
    }
}

fn main() {
    // Create a reader
    let mut veccy = MyVec { buffer: vec![1, 2, 3, 4, 5] };

    // Doesn't work :(
    let res = veccy.next();
}
Run Code Online (Sandbox Code Playgroud)

编译器输出:

/// A generic trait for reading u32s
trait MyReader {
    fn get_next(&mut self) -> Option<u32>;
}

/// Which means we should be able to iterate over the reader, yielding u32s
impl Iterator for MyReader {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        self.get_next()
    }
}

/// Example of a 'reader'
struct MyVec {
    buffer: Vec<u32>,
}

/// This can act as a reader
impl MyReader for MyVec {
    fn get_next(&mut self) -> Option<u32> {
        self.buffer.pop()
    }
}

fn main() {
    // Create a reader
    let mut veccy = MyVec { buffer: vec![1, 2, 3, 4, 5] };

    // Doesn't work :(
    let res = veccy.next();
}
Run Code Online (Sandbox Code Playgroud)

是 Rust 游乐场上的代码。

在我看来,既然MyVecimplements MyReader,那么它应该可以用作迭代器,因此我应该能够调用.next()它。既然我已经实现了MyReader,那么我应该Iterator免费获得一个实现,对吧?该行impl Iterator for ...显示Iterator在范围内,所以我无法理解错误来自哪里。

Ant*_*ony 5

这条线不会像你想象的那样做。

impl Iterator for MyReader {
Run Code Online (Sandbox Code Playgroud)

这实现Iteratortrait object MyReader。您想要的是Iterator为每个也实现MyReader. 不幸的是,由于一致性规则,这是不可能的。

在 Rust 中,你只能在定义 trait 的 crate 或定义你正在实现它的类型的 crate 中实现一个 trait。(对于泛型类型,事情有点复杂,但这是基本思想。)在这种情况下,Iterator是标准库中的一个特征,因此您无法在未定义的任意类型上实现它。如果您考虑一下,这是有道理的,因为否则,如果这些类型之一具有预先存在的实现Iterator- 将使用哪一个?

一种解决方案是将实现的类型包装MyReader在一个 newtype 中,并Iterator在其上实现。由于您自己定义了 newtype,因此您可以自由地对其进行实现Iterator