Rust实现迭代器

洒水器

因此,我目前正在学习Rust,并对如何实现非消耗迭代器有疑问。我编写了一个堆栈:

struct Node<T>{
    data:T,
    next:Option<Box<Node<T>>>
}
pub struct Stack<T>{
    first:Option<Box<Node<T>>>
}
impl<T> Stack<T>{
    pub fn new() -> Self{
        Self{first:None}
    }
    pub fn push(&mut self, element:T){
        let old = self.first.take();
        self.first = Some(Box::new(Node{data:element, next:old}));
    }
    pub fn pop(&mut self) -> Option<T>{
        match self.first.take(){
            None => None,
            Some(node) =>{
                self.first = node.next;
                Some(node.data)
            }
        }
    }
    pub fn iter(self) -> StackIterator<T>{
        StackIterator{
            curr : self.first
        }
    }
}
pub struct StackIterator<T>{
    curr : Option<Box<Node<T>>>
}
impl<T> Iterator for StackIterator<T>{
    type Item = T;
    fn next (&mut self) -> Option<T>{
        match self.curr.take(){
            None => None,
            Some(node) => {
                self.curr = node.next;
                Some(node.data)
            }
        }
    }
}

使用堆栈迭代器,它是在iter()堆栈上调用方法而创建的问题:我不得不使这种iter()方法消耗其堆栈,因此堆栈只能被迭代一次。如何在不消耗堆栈,不实现复制或克隆特征的情况下实现此方法?

感谢您的帮助,对于最基本的问题也很抱歉:)

马斯林

如何在不消耗堆栈,不实现复制或克隆特征的情况下实现此方法?

让StackIterator借用堆栈,并且迭代器返回对项目的引用。遵循以下原则

impl<T> Stack<T>{
    pub fn iter(&self) -> StackIterator<T>{
        StackIterator{
            curr : &self.first
        }
    }
}
pub struct StackIterator<'stack, T: 'stack>{
    curr : &'stack Option<Box<Node<T>>>
}
impl<'s, T: 's> Iterator for StackIterator<'s, T>{
    type Item = &'s T;
    fn next (&mut self) -> Option<&'s T>{
        match self.curr.as_ref().take() {
            None => None,
            Some(node) => {
                self.curr = &node.next;
                Some(&node.data)
            }
        }
    }
}

(我实际上没有测试此代码,因此很可能无法正常工作)

这是本质是什么std::iter::Iter呢(虽然它的实现方式较低的水平)。

那就是说,通过实现链接列表来学习Rust可能不是世界上最好的主意,链接列表是退化的图形,并且借位检查器与图形的关系不是很友好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章