开发者

Create Iterator that yields references to to fields

I would like to define a struct that implements Iterator such that the items yielded are references to one of the the struct's fields.

Lets say I have defined my struct like this:

struct InnerType;
struct MyStruct {
    开发者_运维百科field: InnerType
}

The following does not work because the Associated Type Item requires an explicit lifetime parameter:

impl Iterator for MyStruct {
    type Item = &InnerType;
    fn next(&mut self) -> Option<Self::Item> { Some(&self.field) }
}

Adding a lifetime parameter there doesn't work either because "the lifetime parameter 'a is not constrained by the impl trait, self type, or predicates".

impl<'a> Iterator for MyStruct {
    type Item = &'a InnerType;
    fn next(&mut self) -> Option<Self::Item> { Some(&self.field) }
}

Not sure what I'm missing. What is going on here? Is there some reason(s) not to have an iterator which yields items borrowing from itself?


Is this really what you want? Or would you rather want it so that someone can request an iterator over MyStruct, the way someone would call iter() on a Vec?

If that's the case, you're lucky. You just need a different struct actually implementing the Iterator trait and that struct will contain a reference to field.

struct InnerType;
struct MyStruct {
    field: InnerType
}

struct MyIterator<'a> {
    field: &'a InnerType
}

impl MyStruct {
    fn iter<'a>(&'a self) -> MyIterator<'a> {
        MyIterator{ field: &self.field }
    }
}

impl<'a> Iterator for MyIterator<'a> {
    type Item = &'a InnerType;
    fn next(&mut self) -> Option<Self::Item> { Some(self.field) }
}

fn main() {
    let foo: InnerType = InnerType{};
    
    let my_struct = MyStruct{ field: foo };
    
    let mut it = my_struct.iter();
    
    let item = it.next();
    
    assert!(item.is_some());
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=795bc0433a3a4e621486ecddf8f0a787

Otherwise, there's some discussions on here already about the issue with "streaming iterators", that is, iterators that return references to items in self.

See, for example, here: Iterator lifetime issue when returning references to inner collection

Now this mentions that Generic Associated Types would be required. And those have now made their way into stable Rust (1.65) but I'm not sure if that means that the standard Iterator trait now supports that type of streaming iterator.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜