问题描述
在Rust 1.0之前,我可以使用这种过时的关闭语法编写结构:
Before Rust 1.0, I could write a structure using this obsolete closure syntax:
struct Foo {
pub foo: |usize| -> usize,
}
现在我可以做类似的事情:
Now I can do something like:
struct Foo<F: FnMut(usize) -> usize> {
pub foo: F,
}
但那是什么类型我创建的 Foo
对象?
But then what's the type of a Foo
object I create?
let foo: Foo<???> = Foo { foo: |x| x + 1 };
我还可以使用参考:
struct Foo<'a> {
pub foo: &'a mut FnMut(usize) -> usize,
}
我认为这比较慢,因为
- 指针取消引用
- 对于
FnMut
的类型没有专门的说明实际上最终被使用了
- the pointer dereference
- there's no specialization for the type of
FnMut
that actually ends up being used
推荐答案
在第三个代码段中使用哪种类型,不是一个;闭包类型是匿名的,不能直接命名。相反,您应该这样写:
For what type you'd use in your third code snippet, there isn't one; closure types are anonymous and cannot be directly named. Instead, you'd write:
let foo = Foo { foo: |x| x + 1 };
如果要在需要 指定的上下文中编写代码想要 Foo
,您会这样写:
If you're writing code in a context where you need to specify that you want a Foo
, you'd write:
let foo: Foo<_> = Foo { foo: |x| x + 1 };
_
告诉类型系统进行推断
The _
tells the type system to infer the actual generic type for you.
要使用的 的一般经验法则,按降序排列:
The general rule of thumb as to which to use, in descending order:
- 通用参数:
struct Foo< F:FnMut(usize)-> usize>
。这是最有效的,但这确实意味着特定的Foo
实例只能存储一个闭包,因为每个闭包具有不同的具体类型 - 特质引用:
&'a mut dyn FnMut(usize)->。使用
。有一个指针间接寻址,但是现在您可以存储对具有兼容调用签名的任何闭包的引用。 - 盒装闭包:
Box< dyn FnMut(usize)- > usize>
。这涉及在堆上分配闭包,但是您不必担心生存期。与参考文献一样,您可以存储具有兼容签名的任何闭包。
- Generic parameters:
struct Foo<F: FnMut(usize) -> usize>
. This is the most efficient, but it does mean that a specificFoo
instance can only ever store one closure, since every closure has a different concrete type. - Trait references:
&'a mut dyn FnMut(usize) -> usize
. There's a pointer indirection, but now you can store a reference to any closure that has a compatible call signature. - Boxed closures:
Box<dyn FnMut(usize) -> usize>
. This involves allocating the closure on the heap, but you don't have to worry about lifetimes. As with a reference, you can store any closure with a compatible signature.
使用 |||
语法的闭包是对存储在堆栈中的闭包的引用,使其等效于&'a mut FnMut(使用)->使用
。旧式 proc
是堆分配的,等效于 Box< dyn FnOnce(usize)->。 usize>
(您只能调用一次 proc
)。
Closures that used the ||
syntax were references to closures stored on the stack, making them equivalent to &'a mut FnMut(usize) -> usize
. Old-style proc
s were heap-allocated and were equivalent to Box<dyn FnOnce(usize) -> usize>
(you can only call a proc
once).
这篇关于如何在Rust的结构中存储闭包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!