How do I write an iterator that returns references to itself?

前端 未结 3 1001
故里飘歌
故里飘歌 2020-11-22 14:18

I am having trouble expressing the lifetime of the return value of an Iterator implementation. How can I compile this code without changing the return value of

3条回答
  •  遥遥无期
    2020-11-22 15:04

    As mentioned in other answers, this is called a streaming iterator and it requires different guarantees from Rust's Iterator. One crate that provides such functionality is aptly called streaming-iterator and it provides the StreamingIterator trait.

    Here is one example of implementing the trait:

    extern crate streaming_iterator;
    
    use streaming_iterator::StreamingIterator;
    
    struct Demonstration {
        scores: Vec,
        position: usize,
    }
    
    // Since `StreamingIterator` requires that we be able to call
    // `advance` before `get`, we have to start "before" the first
    // element. We assume that there will never be the maximum number of
    // entries in the `Vec`, so we use `usize::MAX` as our sentinel value.
    impl Demonstration {
        fn new() -> Self {
            Demonstration {
                scores: vec![1, 2, 3],
                position: std::usize::MAX,
            }
        }
    
        fn reset(&mut self) {
            self.position = std::usize::MAX;
        }
    }
    
    impl StreamingIterator for Demonstration {
        type Item = i32;
    
        fn advance(&mut self) {
            self.position = self.position.wrapping_add(1);
        }
    
        fn get(&self) -> Option<&Self::Item> {
            self.scores.get(self.position)
        }
    }
    
    fn main() {
        let mut example = Demonstration::new();
    
        loop {
            example.advance();
            match example.get() {
                Some(v) => {
                    println!("v: {}", v);
                }
                None => break,
            }
        }
    
        example.reset();
    
        loop {
            example.advance();
            match example.get() {
                Some(v) => {
                    println!("v: {}", v);
                }
                None => break,
            }
        }
    }
    

    Unfortunately, streaming iterators will be limited until generic associated types (GATs) from RFC 1598 are implemented.

提交回复
热议问题