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你想要一个盒装特征对象 Box<dyn Bar> , 编译器会自动添加一个 'static生命周期限制(在 RFC 599 中指定)。这意味着 Box<dyn Bar>Box<dyn Bar + 'static>是等价的!

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

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)来绑定(bind):

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

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

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

相关文章:

rust - 关于理解生命周期的问题

rust - 如何在结构体中的数组 block 上实现迭代器?

string - 生命周期如何作用于常量字符串/字符串文字?

rust - 如何在 Rust 中绑定(bind) `Output` 类型的运算符特征?

iterator - 在拥有这些函数的结构上应用一些函数

rust - 为什么我在 Rust Playground 上得到 "Response was not JSON"?

rust - 通过变量访问结构字段

rust - 多个结构字段如何成为使用相同更高生命周期的泛型?

macros - 我找不到 `mock!` 的定义

reference - 在 Vec 中混合引用的生命周期