Generics 对于创建容器、向容器中添加项,然后对这些项进行迭代的泛型函数,值的有效期不够长

Generics 对于创建容器、向容器中添加项,然后对这些项进行迭代的泛型函数,值的有效期不够长,generics,iterator,rust,traits,lifetime,Generics,Iterator,Rust,Traits,Lifetime,我正在尝试编写一个泛型函数,它创建一个默认值并遍历它的内部“缓冲区”。所有这些都发生在函数中,没有参数也没有返回值。我似乎有生命周期声明错误,我有一个困难的时间设置正确的工作 下面是一个示例类型,它实现了Default和IntoIterator特性,以及一个名为Foo的新特性,该特性需要一个方法 trait Foo<T> { fn add(&mut self, T); } struct FooBar<T> { buf: Vec<Option

我正在尝试编写一个泛型函数,它创建一个默认值并遍历它的内部“缓冲区”。所有这些都发生在函数中,没有参数也没有返回值。我似乎有生命周期声明错误,我有一个困难的时间设置正确的工作

下面是一个示例类型,它实现了
Default
IntoIterator
特性,以及一个名为
Foo
的新特性,该特性需要一个方法

trait Foo<T> {
    fn add(&mut self, T);
}

struct FooBar<T> {
    buf: Vec<Option<T>>,
    len: usize,
}

impl<T> FooBar<T> {
    fn new() -> Self {
        let buf = Vec::new();
        let len = 0;
        Self { buf, len }
    }

    fn iter(&self) -> FooBarIter<T> {
        FooBarIter { foo: self, pos: 0 }
    }
}

impl<T> Foo<T> for FooBar<T> {
    fn add(&mut self, val: T) {
        self.buf.push(Some(val));
        self.len += 1;
    }
}

impl<T> Default for FooBar<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<'a, T: 'a> IntoIterator for &'a FooBar<T> {
    type Item = &'a T;
    type IntoIter = FooBarIter<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}
泛型函数创建一个默认值,添加一些项(类型为
&str
),然后通过引用对它们进行迭代。我似乎错误地声明了生命周期,因为Rust抱怨
FooBar
的借来值没有足够长的寿命。但是,它说它会一直存活到函数结束,所以我不知道Rust期望借来的函数实际存活多久

fn start<'a, T: 'a>()
where
    T: Foo<&'a str> + Default,
    &'a T: IntoIterator<Item = &'a &'a str>,
{
    let mut f = T::default();
    f.add("abcd");
    f.add("efgh");

    for val in &f {
        println!("{}", *val);
    }

    f.add("ijkl");

    for val in &f {
        println!("{}", *val);
    }
}

fn main() {
    start::<FooBar<&str>>();
}
我还尝试为
&'a IntoIterator
特性设置不同的生存期参数,但最终我会在循环中寻找其他错误,并没有真正接近设置正确的生存期

为了进一步说明我试图用
FooBar
实现的目标,下面是一个示例,说明如果
FooBar
是一个
Vec
,我将尝试做什么

fn start() {
    let mut f = Vec::new();
    f.push("abcd");
    f.push("efgh");

    for val in &f {
        println!("{}", *val);
    }

    f.push("ijkl");

    for val in &f {
        println!("{}", *val);
    }
}

我是否在正确的轨道上尝试找出生命周期参数,或者完全是其他原因?

我相信你目前的尝试是不可能的

首先,错误消息是因为调用方在传递到
start
时指定了生存期:

fn start<'a, T: 'a>()
编译器不知道如何将调用站点上声明的生存期与HRTB指定的生存期相匹配。我相信,但不确定,这可能会解决问题。

感谢您用HRTBs为我指明了正确的方向。在阅读了这个主题之后,我能够让函数本身提供
FooBarIter
的生存期,而不是
FooBarIter::Item
FooBarIter
现在可以借用,并且可以一直使用到函数结束。调用方仍然可以提供
FooBar
的生存期

这是我唯一需要做的修改,以使它最终编译

fn start<'a, T>()
where
    T: Foo<&'a str> + Default,
    for<'b> &'b T: IntoIterator<Item = &'b &'a str>,
{
    let mut f = T::default();
    f.add("abcd");
    f.add("efgh");

    for val in &f {
        println!("{}", *val);
    }

    f.add("ijkl");

    for val in &f {
        println!("{}", *val);
    }
}
fn开始+默认值,
对于
trait Foo<T> {
    fn add(&mut self, T);
}

impl<T> Foo<T> for Vec<T> {
    fn add(&mut self, val: T) {
        self.push(val);
    }
}

fn start<T>()
where
    T: Default + Foo<&'static str>,
    for<'a> &'a T: IntoIterator,
    for<'a, 'b> &'a <&'b T as IntoIterator>::Item: std::fmt::Display,
{
    let mut f = T::default();
    f.add("abcd");
    f.add("efgh");

    for val in &f {
        println!("{}", &val);
    }

    f.add("ijkl");

    for val in &f {
        println!("{}", &val);
    }
}

fn main() {
    start::<Vec<&str>>();
}
fn start<'a, T>()
where
    T: Foo<&'a str> + Default,
    for<'b> &'b T: IntoIterator<Item = &'b &'a str>,
{
    let mut f = T::default();
    f.add("abcd");
    f.add("efgh");

    for val in &f {
        println!("{}", *val);
    }

    f.add("ijkl");

    for val in &f {
        println!("{}", *val);
    }
}