本文介绍了在Rust中,什么是`fn()-&gt ;?()`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解Fn(大写F)特征: Fn FnMut FnOnce .我了解它们是特质,并且像特质一样工作.

I have a grasp of the Fn (capital-F) traits: Fn, FnMut, FnOnce. I understand that they are traits and work like traits.

但是 fn (小写的-f)呢?在编辑器中它的颜色不同,这告诉我这不是特质.它也可以在其他地方无法使用的地方使用(反之亦然),尽管在其他情况下它的表现也类似.我找不到直接在文档中对其进行解释的内容.

But what about fn (lowercase-f)? It gets a different coloring in editors, which tells me it's not a trait. It can also be used in some places where the others can't (and vice-versa), though it seems to behave similarly in other cases. I couldn't find anything explaining it directly in the docs.

推荐答案

prog-fh的答案本质上是正确的,但是缺乏细微差别.Rust具有三种类似于函数的类型:

prog-fh's answer is essentially correct, but lacks some nuance. Rust has three kinds of function-like types:

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

  1. Function items are what you get when you create a function by using fn foo() {...}. It's also the type of the constructor of a tuple-like struct or enum variant. Function items are zero-sized (they contain no data), and every non-generic function has a unique, unnameable function item type. In error messages, the compiler displays these "Voldemort types" as something like fn() -> () {foo} (with the name of the function in {}).

关闭 是类似于函数项的值,但是闭包可能包含数据:它们从环境中捕获的任何变量的副本或引用.如您所知,您可以使用闭包语法( | args |表达式)创建一个闭包.像函数项一样,闭包具有唯一的,无法命名的类型(由编译器呈现为 [closure@src/main.rs:4:11:4:23] 之类的东西).

Closures are values similar to function items, but closures may contain data: copies of or references to whatever variables they capture from their environment. As you already know, you create a closure by using closure syntax (|args| expression). Like function items, closures have unique, unnameable types (rendered by the compiler something like [closure@src/main.rs:4:11: 4:23]).

函数指针 是您要问的问题:类似于 fn()->的类型.().函数指针不能包含数据,但是大小不能为零.顾名思义,它们是指针.函数指针可以指向函数项,也可以指向不捕获任何内容的闭包,但不能为空.

Function pointers are what you're asking about: the types that look like fn() -> (). Function pointers cannot contain data, but they are not zero-sized; as their name suggests, they are pointers. A function pointer may point either to a function item, or to a closure that captures nothing, but it cannot be null.

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

Function items and closures are automatically coerced to the relevant function pointer type when possible, so that's why let f: fn(i32) = |_| (); works: because the closure captures nothing, it can be coerced to a function pointer.

所有三种类似于函数的类型均实现相关的 Fn FnMut FnOnce 特征(除非闭包可能不实现 Fn FnMut (取决于它们捕获的内容).函数项和函数指针还实现 Copy Clone Send Sync (闭包仅在所有他们的内容呢.)

All three function-like types implement the relevant Fn, FnMut and FnOnce traits (except that closures might not implement Fn or FnMut depending on what they capture). Function items and function pointers also implement Copy, Clone, Send and Sync (closures only implement these traits when all their contents do).

在性能方面,函数指针是泛型和特征对象之间的折衷方案.必须取消引用它们才能调用它们,因此调用函数指针可能比直接调用函数项或闭包慢,但仍比调用 dyn Fn 特征对象快,后者涉及到vtable查找.除了间接调用.

Performance-wise, function pointers are something of a compromise between generics and trait objects. They have to be dereferenced to be called, so calling a function pointer may be slower than calling a function item or closure directly, but still faster than calling a dyn Fn trait object, which involves a vtable lookup in addition to the indirect call.

这篇关于在Rust中,什么是`fn()-&gt ;?()`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 20:52