Box<Fn() + Send + 'static>
生锈是什么意思?
我在阅读高级类型章节时偶然发现了这种语法。Send
是一个特征,但是对于类型参数化中的特征(在这种情况下)来说,这对+
一生意味着什么?'static
又是什么Fn()
?
Box<Fn() + Send + 'static>
生锈是什么意思?
我在阅读高级类型章节时偶然发现了这种语法。Send
是一个特征,但是对于类型参数化中的特征(在这种情况下)来说,这对+
一生意味着什么?'static
又是什么Fn()
?
让我们一一分解。
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()
这是一个特征,就像Clone
or一样Default
。但是,它使用了一种特殊的语法糖。
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) -> R
meanx: T
是一个带有参数A1, ..., An
和返回类型的可调用对象R
。示例包括函数指针和闭包。
Send
意味着这种类型的值可以跨线程发送。由于这是一个自动特征,因此可以将其指定为类型的第二个边界(dyn
特征对象类型)。
'static
边界事实上,dyn
类型(特征对象类型)必须只有一个生命周期限制。省略时推断。推理规则在RFC 0192和RFC 1156中描述。基本上如下:
Box<Any>
是Box<Any + 'static>
因为Any: 'static
。&'a Fn()
是&'a (Fn() + 'a)
。'static
(对于函数签名)或匿名生命周期(对于函数体)。f: Box<Fn() + Send + 'static>
是指向可调用值(原始类型未知且动态更改)的拥有指针,例如闭包(没有参数或没有返回值),它可以跨线程发送并且与程序本身一样长。
我发现该'static
部分需要从最高投票的答案中进行更多详细说明。
将底层具体类型表示为A
。
特征对象Box<dyn Fn() + Send + 'static>
可以从 的实例构造A
,这意味着A: Fn() + Send + 'static
。也就是说,具体类型A
是有static
生命周期的。
as trait bound的具体解释:'static
作为 trait bound,这意味着该类型不包含任何非静态引用。例如。接收者可以随心所欲地保留该类型,并且在他们丢弃它之前它永远不会变得无效。
重要的是要理解这意味着任何拥有的数据总是通过
'static
生命周期的限制,但对该拥有数据的引用通常不会
对于将任何生命周期用作特征绑定的情况的生成性解释:
T: 'a 意味着 T 的所有生命周期参数都超过了 'a。例如,如果 'a 是一个不受约束的生命周期参数,则 i32: 'static 和 &'static str: 'a 满足但 Vec<&'a ()>: 'static 不满足。
对于我们的例子,所有生命周期参数A
must outlive 'static
,例如
pub struct A<'a> {
buf: &'a[u8]
}
达不到要求A: 'static
。