微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Rust 实现迭代器

如何解决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 所做的(尽管它以方式较低级别实现)。

也就是说通过实现链表 probably isn't the best idea in the world 来学习 Rust,链表是退化图,借用检查器与图的关系不是很友好。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。