繁体   English   中英

在 Rust 中,什么是 `fn() -> ()`?

[英]In Rust, what is `fn() -> ()`?

我掌握了 Fn(大写-F)特征: FnFnMutFnOnce 我知道它们是特质,并且像特质一样工作。

但是fn (小写-f)呢? 它在编辑器中有不同的颜色,这告诉我这不是特征。 它也可以用在其他地方不能使用的地方(反之亦然),尽管在其他情况下它的行为似乎相似。 我在文档中找不到任何直接解释它的内容。

prog-fh 的答案基本上是正确的,但缺乏一些细微差别。 Rust 有三种类似函数的类型:

  1. 函数项是您使用fn foo() {...}创建函数时得到的。 它也是类似元组的结构或枚举变体的构造函数的类型。 函数项的大小为零(它们不包含数据),并且每个非泛型函数都有一个唯一的、无法命名的函数项类型。 在错误消息中,编译器将这些“Voldemort 类型”显示为类似fn() -> () {foo} (函数名称在{} )。

  2. 闭包是类似于函数项的值,但闭包可能包含数据:它们从环境中捕获的任何变量的副本或引用。 如您所知,您可以使用闭包语法( |args| expression )创建闭包。 和函数项一样,闭包也有唯一的、 [closure@src/main.rs:4:11: 4:23]类型(由编译器渲染,类似于[closure@src/main.rs:4:11: 4:23] )。

  3. 函数指针就是你要问的:看起来像fn() -> () 函数指针不能包含数据,但它们不是零大小的; 顾名思义,它们是指针。 一个函数指针可以指向一个函数项,也可以指向一个不捕获任何东西的闭包,但它不能为空。

函数项和闭包会在可能的情况下自动强制为相关的函数指针类型,这就是为什么let f: fn(i32) = |_| (); let f: fn(i32) = |_| (); 有效:因为闭包不捕获任何内容,因此可以将其强制转换为函数指针。

所有三个类似函数的类型都实现了相关的FnFnMutFnOnce特性(除了闭包可能不会实现FnFnMut取决于它们捕获的内容)。 函数项和函数指针还实现了CopyCloneSendSync (闭包仅在其所有内容都实现时才实现这些特征)。

在性能方面,函数指针是泛型和特征对象之间的折衷。 它们必须被取消引用才能被调用,因此调用函数指针可能比直接调用函数项或闭包慢,但仍比调用dyn Fn trait 对象快,后者除了间接调用外还涉及 vtable 查找。 然而,在实际代码中,有许多变量会混淆幼稚的分析; 如果性能差异对您很重要,您应该测量它而不是猜测哪个更快。

参考

它是一个函数指针类型

它是指只有一个功能,而不是一个封闭的,因为它包含的功能不捕捉环境中的闭合需要的只是地址。

Fn trait(大写 F)既可以指代闭包,也可以指代函数。

fn 是函数指针的类型。 另请参阅文档中的此处: https : //doc.rust-lang.org/std/primitive.fn.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM