什么"Box <Fn()+发送+'静态>"是生锈的意思?

sou*_*ics 9 types traits lifetime rust lifetime-scoping

Box<Fn() + Send + 'static>生锈意味着什么?

我在阅读高级类型章节时偶然发现了这种语法.Send是一种特质,但对于类型参数化中+的特征('static在这种情况下)的生命周期是什么意思?还有什么Fn()

Mas*_*ara 21

让我们一个一个地分解它.

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

特质对象

Box<Fn() + Send + 'static>,Fn() + Send + 'static是一个特质对象类型.将来,它将被编写Box<dyn (Fn() + Send + 'static)>以避免混淆.

里面dyn是对原始类型的限制.只有在Box<T>被迫Box<Fn() + Send + 'static>时才能被强迫T: Fn() + Send + 'static.因此,虽然我们不知道原始类型,但我们可以假设它是Fn()Send并且'static生命.

Fn()

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

  • Fn(A1, ..., An)是一种语法糖Fn<(A1, ..., An), Output=()>.
  • Fn(A1, ..., An) -> R是一种语法糖Fn<(A1, ..., An), Output=R>.
  • 这句法糖也适用于以下特点:Fn,FnMut,FnOnce,和FnBox.

Fn意味着什么?T: Fn(A1, ..., An) -> Rmeans x: T是一个带有参数A1, ..., An和返回类型的可调用对象R.示例包括函数指针和闭包.

发送

Send表示可以跨线程发送此类型的值.由于这是一个自动的性状,它可以被指定为所述第二边界dyn类型(性状对象类型).

'static

实际上,dyn类型(特征对象类型)必须只有一个生命周期绑定.省略时推断出它.RFC 0192RFC 1156中描述了推理规则.它基本上如下:

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

结论

f: Box<Fn() + Send + 'static> 是一个拥有指向可调用值的指针(原始类型未知并动态更改),例如闭包(没有参数或没有返回值),它可以跨线程发送,并且与程序本身一样长.


Iza*_*ana 8

我发现这部分需要从投票最高的答案'static中进行更多阐述。

基础具体类型表示为A

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

as特征绑定的具体解释:'static

作为特征绑定,这意味着该类型不包含任何非静态引用。例如。接收者可以根据需要保留该类型,并且在丢弃该类型之前该类型永远不会变得无效。

重要的是要理解这意味着任何拥有的数据总是经过'static生命周期限制,但对该拥有的数据的引用通常不会

对于任何生命周期用作特征界限的情况的生成解释

T: 'a 意味着T 的所有生命周期参数都比 'a 长。例如,如果 'a 是无约束生命周期参数,则满足 i32: 'static 和 &'static str: 'a ,但 Vec<&'a ()>: 'static 则不满足。

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

pub struct A<'a> {
   buf: &'a[u8]
}
Run Code Online (Sandbox Code Playgroud)

不能满足A: 'static要求。