如何解决返回对成员迭代器的引用
我有一个结构体,它在借用的切片上有一个迭代器,我想创建一个方法来返回一个迭代器,该迭代器对包含的迭代器进行一些计算
基本上是这样:
#[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 self
的 iter()
以便仅在返回的迭代器上调用 &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 举报,一经查实,本站将立刻删除。