我正在读async book.section async lifetimes中有一段代码片段的语法我不熟悉:

fn foo_expanded<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
    async move { *x }
}

impl Future<Output = u8> + 'a中,impl Trait + 'lifetime是什么?

更新:我更多的是问它是什么,而不是终身逻辑的解释.官方文件中的定义如下:

推荐答案

这里impl Trait + 'lifetime是多少?

它是一个Impl特征,这里特别用作抽象返回类型

Impl特征

Syntax

ImplTraitType : impl TypeParamBounds
ImplTraitTypeOneBound : impl TraitBound

impl Trait提供了指定未命名但具体的类型的方法

trait Trait {}

// argument position: anonymous type parameter
fn foo(arg: impl Trait) {
}

// return position: abstract return type
fn bar() -> impl Trait {
}

其中the grammar of TypeParamBounds允许特征和生命周期 界限

特征和生命周期 界限

Syntax

TypeParamBounds :
   TypeParamBound ( + TypeParamBound )* +?

TypeParamBound :
      Lifetime | TraitBound

TraitBound :
      ?? ForLifetimes? TypePath
   | ( ?? ForLifetimes? TypePath )

LifetimeBounds :
   ( Lifetime + )* Lifetime?

Lifetime :
      LIFETIME_OR_LABEL
   | 'static
   | '_

特别注意,TypeParamBounds的语法是一个或可选地几个TypeParamBound的组合,每个TypeParamBound依次是TraitBoundLifetime(边界).

Specifying Multiple Trait Bounds with the + Syntax详细描述了我们可以组合多个特征界限,但这同样适用于生命周期 界限(在语法允许的情况下).有人可能会争辩说,这一节还应该提到生命周期 界限.

Rust相关问答推荐

收集RangeInclusive T到Vec T<><>

访问Rust中的隐藏变量

如何在原始字符串中转义";#和#";

为什么`Vec i64`的和不知道是`Option i64`?

如果LET;使用布尔表达式链接(&Q);

为潜在的下游实现使用泛型绑定而不是没有泛型绑定的trait

在自定义序列化程序中复制serde(With)的行为

异步函数返回的future 生存期

为什么`AlternateScreen`在读取输入键时需要按Enter键?

在为第三方 struct 实现第三方特征时避免包装器的任何方法

如何从宏调用闭包?

要求类型参数有特定的大小?

如何在 Rust 中将函数项变成函数指针

str 和 String 的 Rust 生命周期

decltype、dyn、impl traits,重构时如何声明函数的返回类型

以 `static` 为前缀的闭包是什么意思?我什么时候使用它?

Rust 函数指针似乎被borrow 判断器视为有状态的

如果我不想运行析构函数,如何移出具有析构函数的 struct ?

当 `T` 没有实现 `Debug` 时替代 `unwrap()`

如果我立即等待,为什么 `tokio::spawn` 需要一个 `'static` 生命周期?