Rust 如何为引用自身但不改变自身的迭代器的关联类型指定生存期?

Rust 如何为引用自身但不改变自身的迭代器的关联类型指定生存期?,rust,lifetime,Rust,Lifetime,我有这个结构: struct RepIter<T> { item: T } 这不会编译,因为必须为type Item=&t;指定生存期。寻找一种方法来做到这一点,我发现。第一个解决方案似乎不适用,因为我正在实现一个预先存在的特性。试图直接复制第二个解决方案,我得到如下结果: impl<'a, T> Iterator for &'a RepIter<T> { type Item = &'a T; fn next(self

我有这个结构:

struct RepIter<T> {
    item: T
}
这不会编译,因为必须为
type Item=&t;指定生存期。寻找一种方法来做到这一点,我发现。第一个解决方案似乎不适用,因为我正在实现一个预先存在的特性。试图直接复制第二个解决方案,我得到如下结果:

impl<'a, T> Iterator for &'a RepIter<T> {
    type Item = &'a T;
    fn next(self) -> Option<&'a T> {
        return Some(&self.item);
    }
}
impl<'a, T> Iterator for &'a RepIter<T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        return Some(&self.item);
    }
}
但是现在,self
是一个对引用的引用,对吗?我不知道如何在
RepIter
的实例上调用
next
。例如,这不起作用:

fn main() {
    let mut iter: RepIter<u64> = RepIter { item: 5 };
    let res = iter.next();
}
fn main(){
设mut iter:RepIter=RepIter{item:5};
设res=iter.next();
}
这使我认为我的trait实现可以用更好的方式编写。

正如Shepmaster链接到的中所讨论的,这有点棘手,因为您确实想更改
next()
的类型,但您不能,因为它是trait的一部分。不过,有几种方法可以解决这个问题

只需对代码进行最小的更改,就可以使用
和'a RepIter
上的
迭代器实现:

不过有点不舒服

另一种方法是改变物品的所有权。如果它已被借用,则可以使所有类型很好地匹配:

struct RepIter<'a, T: 'a> {
    item: &'a T,
}

impl<'a, T> Iterator for RepIter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        Some(&self.item)
    }
}

pub fn main() {
    let val: u64 = 5;
    let mut iter = RepIter { item: &val };
    let res = iter.next();
}
struct RepIter{
项目:&'T,
}
恳求{
类型项=&'T;

fn next(&mut self)->Option我建议您将代码编写为:

use std::iter;

fn main() {
    let val = 5u64;
    let mut iter = iter::repeat(&val);
    let res = iter.next();
}

有一件事我还不太明白,您现有的代码几乎可以工作,但只适用于某些
迭代器
方法;那些按值而非引用获取
self
的方法

struct RepIter<T> {
    item: T,
}

impl<'a, T> Iterator for &'a RepIter<T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        return Some(&self.item);
    }
}

fn main() {
    let iter: RepIter<u64> = RepIter { item: 5 };

    // Works
    let res = iter.fuse().next();
    println!("{:?}", res);

    // Doesn't work
    let res = iter.by_ref().next();
    println!("{:?}", res);
}
struct RepIter{
项目:T,
}
恳求{
返回一些(&self.item);
}
}
fn main(){
设iter:RepIter=RepIter{item:5};
//工作
设res=iter.fuse().next();
println!(“{:?}”,res);
//不起作用
设res=iter.by_ref().next();
println!(“{:?}”,res);
}

可能发生了一些有趣的交互。

在设计迭代器时,为集合和该集合上的迭代器指定不同的类型通常很有用。通常,集合将拥有数据,迭代器将从集合借用数据。集合类型通常实现
到迭代器
,而不实现
迭代器
。这意味着创建迭代器分两步进行:我们需要首先创建集合,然后从集合中创建迭代器

这里有一个解决方案,可以将您的
RepIter
类型转换为一个集合。我将使用的命题生成迭代器

use std::iter::{self, Repeat};

struct RepIter<T> {
    item: T,
}

impl<T> RepIter<T> {
    // When IntoIterator is implemented on `&Self`,
    // then by convention, an inherent iter() method is provided as well.
    fn iter(&self) -> Repeat<&T> {
        iter::repeat(&self.item)
    }
}

impl<'a, T> IntoIterator for &'a RepIter<T> {
    type Item = &'a T;
    type IntoIter = Repeat<&'a T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

fn main() {
    let iter: RepIter<u64> = RepIter { item: 5 };

    let res = iter.iter().next();
    println!("{:?}", res);

    let res = iter.iter().fuse().next();
    println!("{:?}", res);

    let res = iter.iter().by_ref().next();
    println!("{:?}", res);
}
使用std::iter::{self,Repeat};
结构报告器{
项目:T,
}
执行报告器{
//在“&Self”上实现IntoIterator时,
//然后按照惯例,还提供了固有的iter()方法。
fn iter(自我)->重复{
iter::repeat(&self.item)
}
}
impl;
fn进入iter(self)->self::进入iter{
self.iter()
}
}
fn main(){
设iter:RepIter=RepIter{item:5};
设res=iter.iter().next();
println!(“{:?}”,res);
设res=iter.iter().fuse().next();
println!(“{:?}”,res);
设res=iter.iter().by_ref().next();
println!(“{:?}”,res);
}

这与但是高度相关,因为它不需要自身变异,实际上是可以解决的。哦。这有点奇怪!我想这是因为编译器只会自动引用一次。为了调用通过值获取
self
的方法,它只需要自动引用一次,但是要调用通过引用获取
self
的方法,它需要自动引用两次。尽管所有答案都非常有用,但我还是会接受这个答案,因为这几乎就是我最后要做的。
struct RepIter<T> {
    item: T,
}

impl<'a, T> Iterator for &'a RepIter<T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        return Some(&self.item);
    }
}

fn main() {
    let iter: RepIter<u64> = RepIter { item: 5 };

    // Works
    let res = iter.fuse().next();
    println!("{:?}", res);

    // Doesn't work
    let res = iter.by_ref().next();
    println!("{:?}", res);
}
use std::iter::{self, Repeat};

struct RepIter<T> {
    item: T,
}

impl<T> RepIter<T> {
    // When IntoIterator is implemented on `&Self`,
    // then by convention, an inherent iter() method is provided as well.
    fn iter(&self) -> Repeat<&T> {
        iter::repeat(&self.item)
    }
}

impl<'a, T> IntoIterator for &'a RepIter<T> {
    type Item = &'a T;
    type IntoIter = Repeat<&'a T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

fn main() {
    let iter: RepIter<u64> = RepIter { item: 5 };

    let res = iter.iter().next();
    println!("{:?}", res);

    let res = iter.iter().fuse().next();
    println!("{:?}", res);

    let res = iter.iter().by_ref().next();
    println!("{:?}", res);
}