"Box<Fn() + Send + 'static>" 在 rust 中是什么意思?

What does "Box<Fn() + Send + 'static>" mean in rust?

rust 中的Box<Fn() + Send + 'static> 是什么意思?

我在阅读高级类型章节时偶然发现了这个语法。 Send 是一个特征,但是在类型参数化中 + 生命周期对特征(在本例中为 'static )意味着什么?还有什么是 Fn() ?

我们一一分解。

盒子

Box<T> 是指向堆分配 T 的指针。我们在这里使用它是因为特征对象只能存在于指针后面。

特征对象

Box<Fn() + Send + 'static>中,Fn() + Send + 'statictrait object type. In future, it will be written Box<dyn (Fn() + Send + 'static)>以避免混淆。

里面dyn是对原始类型的限制。只有当T: Fn() + Send + 'static时,Box<T>才能被强制转换为Box<Fn() + Send + 'static>。因此,虽然我们不知道原始类型,但我们可以假设它是 Fn() and Send and had 'static lifetime.

Fn()

这是一个特征,就像 CloneDefault 一样。但是,它使用了一种特殊的 语法糖 .

  • Fn(A1, ..., An)Fn<(A1, ..., An), Output=()>.
  • 的语法糖
  • Fn(A1, ..., An) -> RFn<(A1, ..., An), Output=R>.
  • 的语法糖
  • 此语法糖也适用于以下特征:Fn, FnMut, FnOnce, and FnBox.

那么Fn是什么意思呢? T: Fn(A1, ..., An) -> R 表示 x: T 是一个参数为 A1, ..., An 且 return 类型为 R 的可调用对象。示例包括函数指针和闭包。

发送

Send means that values of this type can be sent across threads. Since this is an auto trait, it can be specified as the second boundsdyn 类型(特征对象类型)。

'static绑定

事实上,dyn 类型(特征对象类型)必须只有一个生命周期限制。省略时推断。 RFC 0192 and RFC 1156中描述了推理规则。大致如下:

  1. 如果明确给出,则使用该生命周期。
  2. 否则从内在特质推断。例如,Box<Any>Box<Any + 'static> 因为 Any: 'static.
  3. 如果特征没有适当的生命周期,则从外部类型推断。例如,&'a Fn()&'a (Fn() + 'a).
  4. 如果甚至失败,它会回退到 'static(对于函数签名)或匿名生命周期(对于函数体)。

结论

f: Box<Fn() + Send + 'static> 是指向可调用值(原始类型未知且动态更改)的自有指针,例如闭包(没有参数或没有 return 值),可以通过线程和程序本身一样长。

我发现 'static 部分需要 进一步阐述。

底层混凝土类型表示为A

特征对象 Box<dyn Fn() + Send + 'static> 可以从 A 的实例构造,这意味着 A: Fn() + Send + 'static。也就是说,具体类型 A 受限于 static 生命周期。

特定 explanation 'static 作为特征界限:

As a trait bound, it means the type does not contain any non-static references. Eg. the receiver can hold on to the type for as long as they want and it will never become invalid until they drop it.

It's important to understand this means that any owned data always passes a 'static lifetime bound, but a reference to that owned data generally does not

A generative explanation 对于使用任何生命周期作为特征边界的情况:

T: 'a means that all lifetime parameters of T outlive 'a. For example if 'a is an unconstrained lifetime parameter then i32: 'static and &'static str: 'a are satisfied but Vec<&'a ()>: 'static is not.

对于我们的案例,A 的所有生命周期参数必须超过 'static,例如

pub struct A<'a> {
   buf: &'a[u8]
}

无法满足A: 'static要求。