Compilation 在自身上实现一个迭代器,返回一个关于迭代器not impl'的框编译错误;ed,尽管是简单的';预计起飞时间

Compilation 在自身上实现一个迭代器,返回一个关于迭代器not impl'的框编译错误;ed,尽管是简单的';预计起飞时间,compilation,compiler-errors,iterator,rust,Compilation,Compiler Errors,Iterator,Rust,我正在尝试编写一个库,该库将读取字节(例如,从文件中读取),并解析出对象,然后在对象上返回一个interator。然而,我在实现迭代器时遇到了困难,即使是使用虚拟版本 这是我的密码: use std::io::Read; // One of the objects I want to return pub struct ObjA { data: i8, } // There might be other kinds of objects here. pub enum MyObj {

我正在尝试编写一个库,该库将读取字节(例如,从文件中读取),并解析出对象,然后在对象上返回一个interator。然而,我在实现迭代器时遇到了困难,即使是使用虚拟版本

这是我的密码:

use std::io::Read;

// One of the objects I want to return
pub struct ObjA {
    data: i8,
}

// There might be other kinds of objects here.
pub enum MyObj {
    ObjA(ObjA),
}

// There will be other input formats, and I want a generic trait for "read bytes and return MyObj's"
pub trait ObjReader<R> {
    // This should create the parser/reader from a std::io::Read source
    fn new(R) -> Self;

    // This will iterate over the objects. (AFAIK this is how to return an iterator)
    fn objects(&self) -> Box<Iterator<Item=MyObj>>;
}

// The data will be in XML, so here's a stupid struct that will (eventually) parse it and return objects. It obv. takes a `Read`
pub struct XMLReader<R: Read> {
    inner_reader: R,
}

// The XMLReader will be an ObjReader
impl<R: Read> ObjReader<R> for XMLReader<R> {
    fn new(reader: R) -> XMLReader<R> {
        XMLReader { inner_reader: reader }
    }

    // Return the iterator for the objects, I'll keep it simple and iterate over itself, rather than create a new struct
    fn objects(&self) -> Box<Iterator<Item=MyObj>> {
        Box::new(self)
    }
}

// Make XMLReader be an iterator
impl<R: Read> Iterator for XMLReader<R> {
    type Item = MyObj;

    // Right now, it's always empty. This is a stub
    fn next(&mut self) -> Option<Self::Item> {
        None
    }
}

// Dummy main to allow it to compile
fn main() {

}

答案既简单又烦人:您已经为
XMLReader
而不是
&XMLReader
实现了
Iterator
,或者您必须
Box
值而不是引用

前者不会让您走得更远,因为这样您将尝试在引用周围创建一个
。。。有两种可能性:

  • 为读取器和迭代器提供不同的类型
  • 对象
    的签名更改为按值获取
    自身

  • 然后,您还必须注意约束
    R
    ,以确保它不会引用在您完成迭代之前可能停止活动的对象。一个
    '静态
    绑定一开始就比较简单。

    答案既简单又烦人:您已经为
    XMLReader
    实现了
    迭代器
    ,而不是
    &XMLReader
    ,或者您必须
    值而不是引用

    前者不会让您走得更远,因为这样您将尝试在引用周围创建一个
    。。。有两种可能性:

  • 为读取器和迭代器提供不同的类型
  • 对象
    的签名更改为按值获取
    自身

  • 然后,您还必须注意约束
    R
    ,以确保它不会引用在您完成迭代之前可能停止活动的对象。一个静态的绑定一开始会更简单。

    你能举一些例子来说明如何使用1。还是2。?我是生锈的新手,不知道该怎么做。@Rory:我不确定在你的情况下该怎么做,因为我不确定你希望
    XMLReader
    在内部如何工作;(2) 不过,这很简单,只需将签名切换到
    fn objects(self)->…
    ,编译器就会指导您。您能否给出一些示例,说明如何执行上述任一操作1。还是2。?我是生锈的新手,不知道该怎么做。@Rory:我不确定在你的情况下该怎么做,因为我不确定你希望
    XMLReader
    在内部如何工作;(2) 不过,这很简单,只要将签名切换到
    fn objects(self)->…
    ,编译器就会指导您。
    $ multirust run beta rustc test.rs
    test.rs:24:13: 24:27 error: the trait `core::iter::Iterator` is not implemented for the type `&XMLReader<R>` [E0277]
    test.rs:24             Box::new(self)
                           ^~~~~~~~~~~~~~
    test.rs:24:13: 24:27 help: run `rustc --explain E0277` to see a detailed explanation
    test.rs:24:13: 24:27 note: `&XMLReader<R>` is not an iterator; maybe try calling `.iter()` or a similar method
    test.rs:24:13: 24:27 note: required for the cast to the object type `core::iter::Iterator<Item=MyObj> + 'static`
    error: aborting due to previous error
    
    $ multirust run beta rustc --version
    rustc 1.7.0-beta.4 (5ed7d4e31 2016-02-26)