闭包何时实现Fn,FnMut和FnOnce?


114

哪些具体条件为闭合来实现FnFnMutFnOnce特质?

那是:

  • 什么时候关闭实现该FnOnce特性?
  • 什么时候关闭实现该FnMut特性?
  • 什么时候关闭实现该Fn特性?

例如,更改闭包主体的状态会使编译器无法Fn在其上实现。


Answers:


126

每个特征都代表着关于闭包/函数的越来越多的限制性属性,由其call_...方法的签名表示,尤其是self

  • FnOnceself)是可以调用一次的函数
  • FnMut&mut self)是可以&mut访问其环境的函数
  • Fn&self)是只能&访问其环境的函数

闭包|...| ...将自动实现尽可能多的闭包。

  • 所有闭包都实现FnOnce:不能一次调用的闭包不配名称。请注意,如果闭包仅实现FnOnce,则只能调用一次。
  • 不会移出捕获的闭包实现了FnMut,从而可以多次调用它们(如果可以对函数对象进行非别名访问)。
  • 不需要唯一/可变访问其捕获实现的闭包Fn,使它们基本上在任何地方都可以被调用。

这些限制直接源于self闭包类型和结构的“废止”。在我的博客文章“ 在Rust中找到闭包”中有所描述

有关封锁信息,请参阅瓶盖:匿名功能,可以捕捉他们的环境锈病程序设计语言


如果闭包仅实现FnOnce,这是否意味着只能调用一次?
2015年

@nalply,是的,只有一次。
休2015年

9
我误读了纳尔普利的评论,这使我有些困惑。将来的读者请注意,他说“如果闭包实现FnOnce”。
sleeparrow

2
实施细节:将自动实施尽可能多的实施。并非完全正确,如果需要,它将自动实现它们。您可以使用专门化检测用于FnMut参数的闭包缺少的Fn-impl。这是bug github.com/rust-lang/rust/issues/26085
bluss
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.