Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iterator 如何编写一个返回自身引用的迭代器?_Iterator_Rust_Lifetime - Fatal编程技术网

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){