rust - 为什么需要使用加号运算符 (Iterator<Item = &Foo> + 'a) 为特征添加生命周期?

标签 rust lifetime

我在迭代器上应用了一个闭包,我想使用稳定,所以我想返回一个装箱的 Iterator .这样做的明显方法如下:

struct Foo;

fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>> {
    Box::new(myvec.iter())
}

这失败了,因为借用检查器无法推断出适当的生命周期。

经过一番研究,我发现What is the correct way to return an Iterator (or any other trait)? ,这让我添加了 + 'a :
fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'a> {
    Box::new(myvec.iter())
}

但我不明白
  • 这是做什么的
  • 以及这里为什么需要它
  • 最佳答案

    有一件事很容易被忽视:如果你有一个特质 Bar并且你想要一个盒装的 trait 对象 Box<dyn Bar> ,编译器会自动添加一个 'static生命周期限制(在 RFC 599 中指定)。这意味着 Box<dyn Bar>Box<dyn Bar + 'static>是等价的!

    在您的情况下,编译器会自动添加静态绑定(bind),以便 this ...

    fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>>
    

    ...相当于:
    fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'static>
    

    现在生命周期省略规则启动并“连接”两个生命周期,这样上面的代码就相当于:
    fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'static>
    

    但是类型 Iter<'a, Foo> (Vec<Foo> 的特定迭代器类型)显然不满足界限 'static (因为它正在借用 Vec<Foo> )!所以我们必须告诉编译器我们不想要默认的'static。通过指定我们自己的生命周期来绑定(bind):
    fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'a>
    

    现在编译器知道 trait 对象只在生命周期内有效 'a .请注意,我们不需要显式注释相关 Item 的生命周期。类型!终身省略规则可以解决这个问题。

    关于rust - 为什么需要使用加号运算符 (Iterator<Item = &Foo> + 'a) 为特征添加生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62448045/

    相关文章:

    rust - 我可以在 Rust 中实现将信息添加到外部类型的特征吗?

    windows - Rust:如何对SAFESEH图像进行链接不安全

    rust - 指定对关联函数中成员变量的返回参数的引用的生命周期

    rust - 如何为我不拥有的类型实现我不拥有的特征?

    rust - 从 HashSet 获取时发生不可变借用

    GIT 存储说明

    rust - 在 tokio::time::timeout 之后再次等待 future

    c++ - 什么是 "right"在 C++ 中避免别名(例如,将容器的元素添加到自身时)的方法?

    rust - 如何声明一个比其封闭 block 生命周期更长的闭包

    rust - 为什么不能在同一结构中存储值和对该值的引用?