什么时候应该使用函数指针而不是闭包?
When should I use function pointers instead of closures?
我的理解是,实现一个以 impl Fn
作为参数的函数允许 rust 编译器执行更多优化,但是使用 impl Fn
而不是函数指针不应该更多限制性的。
我还可以将函数指针传递给接受 impl Fn
的函数,所以我猜测 Rust 中的函数指针类型仅用作 PhantomData
的通用参数来表达类型差异,在 ffi 中在某些情况下作为 Box<dyn Fn(...) -> ...>
.
的替代方案
impl Fn
类型基本上隐藏了一个类型参数。使函数成为通用函数的任何类型参数都需要为传递给它的每个不同类型重新编译(单态化)函数。因此,与仅采用具体类型(例如此处的函数指针)的非泛型函数相比,泛型函数会导致更长的编译时间和更多的生成代码。因此,您可以使用函数指针来减少项目的总编译时间或二进制文件的大小。
如果需要store提供的函数,impl Fn()
表示放在一个Box<dyn Fn()>
中,通过一个虚表。这比直接调用函数指针多一种间接方式(多一种内存访问)。函数指针可以直接存储在数据结构中,例如Vec<fn(&mut Foo)>
.
(但这并不意味着 Box
将执行分配;如果函数类型不是捕获闭包(相当于“可以强制转换为函数指针”),则它是零大小的类型,因此 Box
不分配。)
正如您已经注意到的,函数指针出现在 FFI 中是因为它们是预期的 ABI,而 impl Fn
或 dyn Fn
是特定于 Rust 的。
我的理解是,实现一个以 impl Fn
作为参数的函数允许 rust 编译器执行更多优化,但是使用 impl Fn
而不是函数指针不应该更多限制性的。
我还可以将函数指针传递给接受 impl Fn
的函数,所以我猜测 Rust 中的函数指针类型仅用作 PhantomData
的通用参数来表达类型差异,在 ffi 中在某些情况下作为 Box<dyn Fn(...) -> ...>
.
impl Fn
类型基本上隐藏了一个类型参数。使函数成为通用函数的任何类型参数都需要为传递给它的每个不同类型重新编译(单态化)函数。因此,与仅采用具体类型(例如此处的函数指针)的非泛型函数相比,泛型函数会导致更长的编译时间和更多的生成代码。因此,您可以使用函数指针来减少项目的总编译时间或二进制文件的大小。如果需要store提供的函数,
impl Fn()
表示放在一个Box<dyn Fn()>
中,通过一个虚表。这比直接调用函数指针多一种间接方式(多一种内存访问)。函数指针可以直接存储在数据结构中,例如Vec<fn(&mut Foo)>
.(但这并不意味着
Box
将执行分配;如果函数类型不是捕获闭包(相当于“可以强制转换为函数指针”),则它是零大小的类型,因此Box
不分配。)正如您已经注意到的,函数指针出现在 FFI 中是因为它们是预期的 ABI,而
impl Fn
或dyn Fn
是特定于 Rust 的。