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

返回对成员迭代器的引用

如何解决返回对成员迭代器的引用

我有一个结构体,它在借用的切片上有一个迭代器,我想创建一个方法来返回一个迭代器,该迭代器对包含的迭代器进行一些计算

基本上是这样:

#[derive(Clone)]
struct Foo<'a>  {
    inner: ::std::iter::Cycle<::std::slice::Iter<'a,u8>>,}


impl<'a> Foo<'a> {
    pub fn new<T: AsRef<[u8]> + ?Sized>(vals: &'a T) -> Foo<'a> {
        Self {
            inner: vals.as_ref().iter().cycle(),}
    }
    pub fn iter(&mut self) -> impl Iterator<Item = u8> + 'a {
        self.inner.by_ref().map(Clone::clone) // simple case but this Could be any computation
    }
}

这会产生一个神秘的错误

这是我的理解:我需要将返回的迭代器的生命周期绑定到 &mut selfiter() 以便仅在返回的迭代器上调用 &mut self 时才会删除 .collect() .

但是,更改为 fn iter(&'a mut self) 还不够好,因为 &'a mut self 现在在结构实例的整个持续时间内都存在(意味着调用 collect() 不会删除该引用)。这可以防止这样的事情

#[test]
fn test(){
    let mut foo = Foo::new("hello,there");
    foo.iter().zip(0..4).collect::<Vec<_>>(); // call once,ok
    foo.iter().zip(0..4).collect::<Vec<_>>(); // error because 2 &mut references exist at the same
}

锈游乐场link

解决方法

我这样做的方法是创建一个仅用于迭代这些项目的结构。这让事情变得容易多了。

    ...

    pub fn iter(&mut self) -> ClonedFooIter<'a,'_> {
        ClonedFooIter {
            inner: &mut self.inner,}
    }
}

pub struct ClonedFooIter<'a,'b> {
    inner: &'b mut std::iter::Cycle<::std::slice::Iter<'a,u8>>,}

impl<'a,'b> Iterator for ClonedFooIter<'a,'b> {
    type Item = u8;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().cloned()
    }
}

这个想法是,返回的结构只存在到 self 的可变借用存在为止。

使用结构体也可以更轻松地命名迭代器类型。

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