如何解决如何编写一个简单地反转迭代的自定义 `IntoIterator` 实现?
我是 Rust 新手,我正在尝试实现具有 struct
的自定义 Vec
。我希望这个自定义结构是可迭代的,并且以相反的顺序在内部 Vec
上迭代。
到目前为止,我所理解的是我需要实现 IntoIterator
特征,并最终实现一个自定义 Iterator
,IntoIterator
将自定义结构转换为该自定义结构。由于我只想反转 Vec
上的迭代,因此我想重新使用标准库已经提供的内容。
这是我的结构:
pub struct BitMap {
content: Vec<u64>,}
这就是我尝试实现 IntoIterator
的方式:
impl<'a> iter::IntoIterator for &'a BitMap {
type Item = u64;
type IntoIter = iter::Rev<slice::Iter<'a,Self::Item>>;
fn into_iter(self) -> Self::IntoIter {
(&(self.content)).iter().rev()
}
}
但是编译器抱怨:
47 | type IntoIter = iter::Rev<slice::Iter<'a,Self::Item>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`,found reference
我正在努力理解如何实现这件简单的事情。
更新
感谢E_net4 says don't copy that的answer!
考虑到您提到您的解决方案需要复制元素,我尝试实现一个试图避免它的版本,这就是我想出的:
impl<'a> iter::IntoIterator for &'a BitMap {
type Item = u64;
type IntoIter = BitMapIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
BitMapIterator::new(&self.content)
}
}
pub struct BitMapIterator<'a> {
content: &'a Vec<u64>,index: usize,}
impl<'a> BitMapIterator<'a> {
fn new(content: &'a Vec<u64>) -> Self {
BitMapIterator {
content,index: content.len(),}
}
}
impl iter::Iterator for BitMapIterator<'_> {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
if self.index == 0 {
None
} else {
self.index -= 1;
Some(self.content[self.index])
}
}
}
但是正如你所看到的,这需要我实现一个自定义的迭代器并将其公开。这似乎是我想要的,如果我在不复制元素的情况下正确理解,但我不知道这个解决方案是多么地道,它基本上不重用 std lib 提供的任何东西。
解决方法
在向量上调用 .iter()
会创建一个非拥有项的迭代器,它将位于不可变引用之后。并且 &u64
个项目的迭代器不能履行 u64
个项目的迭代器的角色。
考虑到 u64
的复制成本很低,用 .copied
修改迭代器就足以获得返回实际值的迭代器。复制的迭代器是惰性的,它只在遍历项目时复制它们。
use std::{iter,slice};
pub struct BitMap {
content: Vec<u64>,}
impl<'a> iter::IntoIterator for &'a BitMap {
type Item = u64;
type IntoIter = iter::Copied<iter::Rev<slice::Iter<'a,Self::Item>>>;
fn into_iter(self) -> Self::IntoIter {
self.content.iter().rev().copied()
}
}
另见:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。