Rust中Peekable迭代器为何返回Option<&&Foo>?如何获取Option<&Foo>?
Peekable迭代器返回双重引用的原因及解决方法
为什么会返回Option<&&Foo>?
首先,foovec.iter()创建的是不可变引用迭代器(Iter<'_, Foo>),这个迭代器每次next()返回的是Option<&Foo>——也就是对Vec中元素的借用引用。
而Peekable的peek()方法作用是预取下一个元素的引用,它不会消耗迭代器,所以返回的是迭代器下一个元素的引用。因为迭代器本身产出的元素是&Foo,对这个元素再取引用就得到了&&Foo,最终包装在Option里就是Option<&&Foo>。
简单总结:迭代器产出&Foo,peek()返回这个产出值的引用,因此形成了两层引用嵌套。
如何转换为Option<&Foo>?
以下几种方法都无需消耗Vec,仅获取元素的借用引用:
方法1:使用copied()
由于&Foo是可Copy的类型(引用本身实现了Copy trait),在迭代器上调用copied()可以将迭代器产出的&Foo转换为复制后的引用(本质是同一个指针的浅复制),之后peek()就会返回Option<&Foo>:
struct Foo {} let mut foovec = vec![]; foovec.push(Foo {}); let mut iter = foovec.iter().copied().peekable(); let next = iter.peek(); // 类型为Option<&Foo>
方法2:手动解引用或使用as_deref()
可以直接对peek()的返回结果进行解引用处理,或者利用as_deref()方法自动处理嵌套引用:
struct Foo {} let mut foovec = vec![]; foovec.push(Foo {}); let mut iter = foovec.iter().peekable(); // 显式解引用 let next = iter.peek().map(|&&x| &x); // 简洁写法:利用Option的copied方法 let next = iter.peek().copied(); // 自动解引用:as_deref适配嵌套引用 let next = iter.peek().as_deref();
方法3:使用cloned()
如果你的类型实现了Clone trait,也可以用cloned()处理,但对于引用来说,copied()更高效(引用的Copy是浅复制,无需调用Clone方法):
struct Foo {} let mut foovec = vec![]; foovec.push(Foo {}); let mut iter = foovec.iter().cloned().peekable(); let next = iter.peek(); // 类型为Option<&Foo>
内容的提问来源于stack exchange,提问作者ccleve
相关产品推荐
相关产品推荐

