Iterator 如何编写一个返回自身引用的迭代器?
我在表示Iterator 如何编写一个返回自身引用的迭代器?,iterator,rust,lifetime,Iterator,Rust,Lifetime,我在表示迭代器实现的返回值的生存期时遇到问题。如何在不更改迭代器返回值的情况下编译此代码?我希望它返回一个引用向量 很明显,我没有正确地使用life参数,但在尝试了我刚刚放弃的各种方法之后,我不知道该如何处理它 use std::iter::Iterator; struct PermutationIterator<T> { vs: Vec<Vec<T>>, is: Vec<usize>, } impl<T> Perm
迭代器
实现的返回值的生存期时遇到问题。如何在不更改迭代器返回值的情况下编译此代码?我希望它返回一个引用向量
很明显,我没有正确地使用life参数,但在尝试了我刚刚放弃的各种方法之后,我不知道该如何处理它
use std::iter::Iterator;
struct PermutationIterator<T> {
vs: Vec<Vec<T>>,
is: Vec<usize>,
}
impl<T> PermutationIterator<T> {
fn new() -> PermutationIterator<T> {
PermutationIterator {
vs: vec![],
is: vec![],
}
}
fn add(&mut self, v: Vec<T>) {
self.vs.push(v);
self.is.push(0);
}
}
impl<T> Iterator for PermutationIterator<T> {
type Item = Vec<&'a T>;
fn next(&mut self) -> Option<Vec<&T>> {
'outer: loop {
for i in 0..self.vs.len() {
if self.is[i] >= self.vs[i].len() {
if i == 0 {
return None; // we are done
}
self.is[i] = 0;
self.is[i - 1] += 1;
continue 'outer;
}
}
let mut result = vec![];
for i in 0..self.vs.len() {
let index = self.is[i];
result.push(self.vs[i].get(index).unwrap());
}
*self.is.last_mut().unwrap() += 1;
return Some(result);
}
}
}
fn main() {
let v1: Vec<_> = (1..3).collect();
let v2: Vec<_> = (3..5).collect();
let v3: Vec<_> = (1..6).collect();
let mut i = PermutationIterator::new();
i.add(v1);
i.add(v2);
i.add(v3);
loop {
match i.next() {
Some(v) => {
println!("{:?}", v);
}
None => {
break;
}
}
}
}
使用std::iter::Iterator;
结构置换迭代器{
vs:Vec,
是:Vec,,
}
置换迭代器{
fn new()->置换迭代器{
置换迭代器{
vs:vec![],
is:vec![],
}
}
fn添加(&mut self,v:Vec){
自我vs.推(v);
自推(0);
}
}
置换迭代器的impl迭代器{
类型Item=Vec=self.vs[i].len(){
如果i==0{
返回None;//我们完成了
}
self.is[i]=0;
self.is[i-1]+=1;
继续"走出去",;
}
}
让mut result=vec![];
对于0..self.vs.len()中的i{
设index=self.is[i];
result.push(self.vs[i].get(index.unwrap());
}
*self.is.last_mut().unwrap()+=1;
返回一些(结果);
}
}
}
fn main(){
设v1:Vec=(1..3).collect();
设v2:Vec=(3..5).collect();
设v3:Vec=(1..6).collect();
设mut i=置换迭代器::new();
i、 添加(v1);
i、 添加(v2);
i、 添加(v3);
环路{
比赛一下一场{
一些(v)=>{
println!(“{:?}”,v);
}
无=>{
打破
}
}
}
}
()
错误[E0261]:使用未声明的生存期名称“%a”`
-->src/main.rs:23:22
|
23 | type Item=Vec据我所知,您希望迭代器将引用向量返回到自身中,对吗?不幸的是,这是不可能在生锈
这是精简的迭代器
特性:
trait迭代器{
类型项目;
fn next(&mut self)->选项;
}
请注意,&mut self
和选项之间没有生命周期连接。这意味着next()
方法不能将引用返回到迭代器本身。您无法表示返回引用的生命周期。这基本上就是你找不到一种方法来指定正确的生命周期的原因——它看起来是这样的:
fn下一个选项{
类型项目=Vec>{
...
}
}
注意现在如何在impl
块上声明生存期'a
。这样做是可以的(事实上是必需的),因为您需要在结构上指定生存期参数。然后,您可以在项目
和下一步()
返回类型中使用相同的'a
。同样,这也是大多数集合迭代器的工作方式。正确地解释了代码无法编译的原因。简而言之,它说迭代器不能从自身产生借用值
然而,它可以从其他东西中获得借来的价值。这是通过Vec
和Iter
实现的:Vec
拥有这些值,Iter
只是一个包装器,能够在Vec
中生成引用
这是一个可以实现你想要的设计。迭代器就像Vec
和Iter
一样,只是实际拥有值的其他容器的包装器
使用std::iter::Iterator;
结构置换迭代器{
vs:Vec置换迭代器{…}
fn add(&mut self,v:&a[T]){…}
}
恳求{
类型Item=Vec>{…}
}
fn main(){
设v1:Vec=(1..3).collect();
设v2:Vec=(3..5).collect();
设v3:Vec=(1..6).collect();
设mut i=置换迭代器::new();
i、 添加(&v1);
i、 添加(&v2);
i、 添加(&v3);
环路{
比赛一下一场{
一些(v)=>{println!(“{:?}”,v);}
无=>{break;}
}
}
}
与你最初的问题无关。如果这只是我,我会确保所有借来的向量都是一次性的。其思想是删除对add
的重复调用,并在构建时直接传递所有借用的向量:
使用std::iter::{Iterator,repeat};
结构置换迭代器{
...
}
恳求{
fn新(vs:Vec){
设n=vs.len();
置换迭代器{
vs:vs,
is:重复(0).take(n).collect(),
}
}
}
恳求{
...
}
fn main(){
设v1:Vec=(1..3).collect();
设v2:Vec=(3..5).collect();
设v3:Vec=(1..6).collect();
让vall:Vec=Vec![&v1、&v2、&v3];
设muti=置换迭代器::new(vall);
}
(EDIT:将迭代器设计更改为采用Vec>
。采用引用到容器比构建引用容器更容易。)如其他答案中所述,这被称为流式迭代器,它需要与Rust的迭代器不同的保证。一个提供此类功能的板条箱被恰当地调用,它提供了特性
下面是实现trait的一个示例:
extern crate streaming_iterator;
use streaming_iterator::StreamingIterator;
struct Demonstration {
scores: Vec<i32>,
position: usize,
}
// Since `StreamingIterator` requires that we be able to call
// `advance` before `get`, we have to start "before" the first
// element. We assume that there will never be the maximum number of
// entries in the `Vec`, so we use `usize::MAX` as our sentinel value.
impl Demonstration {
fn new() -> Self {
Demonstration {
scores: vec![1, 2, 3],
position: std::usize::MAX,
}
}
fn reset(&mut self) {
self.position = std::usize::MAX;
}
}
impl StreamingIterator for Demonstration {
type Item = i32;
fn advance(&mut self) {
self.position = self.position.wrapping_add(1);
}
fn get(&self) -> Option<&Self::Item> {
self.scores.get(self.position)
}
}
fn main() {
let mut example = Demonstration::new();
loop {
example.advance();
match example.get() {
Some(v) => {
println!("v: {}", v);
}
None => break,
}
}
example.reset();
loop {
example.advance();
match example.get() {
Some(v) => {
println!("v: {}", v);
}
None => break,
}
}
}
extern板条箱流式迭代器;
使用streaming_iterator::StreamingIterator;
结构演示{
分数:Vec,
位置:usize,
}
//因为'StreamingIterator'要求我们能够调用
//在“得到”之前“前进”,我们必须在“第一个”之前开始
//元素。我们假设永远不会有
//“Vec”中的条目,因此我们使用“usize::MAX”作为哨兵值。
impl演示{
fn new()->Self{
示范{
分数:vec![1,2,3],
位置:std::usize::MAX,
}
}
fn重置(&mut self){