Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does a closure implement Fn, FnMut and FnOnce?

Tags:

closures

rust

What are the specific conditions for a closure to implement the Fn, FnMut and FnOnce traits?

That is:

  • When does a closure not implement the FnOnce trait?
  • When does a closure not implement the FnMut trait?
  • When does a closure not implement the Fn trait?

For instance, mutating the state of the closure on it's body makes the compiler not implement Fn on it.

like image 847
Denilson Amorim Avatar asked May 11 '15 20:05

Denilson Amorim


People also ask

How do you use FnOnce in Rust?

Use FnOnce as a bound when you want to accept a parameter of function-like type and only need to call it once. If you need to call the parameter repeatedly, use FnMut as a bound; if you also need it to not mutate state, use Fn .

What is a closure in Rust?

Rust's closures are anonymous functions you can save in a variable or pass as arguments to other functions. You can create the closure in one place and then call the closure elsewhere to evaluate it in a different context. Unlike functions, closures can capture values from the scope in which they're defined.


1 Answers

The traits each represent more and more restrictive properties about closures/functions, indicated by the signatures of their call_... method, and particularly the type of self:

  • FnOnce (self) are functions that can be called once
  • FnMut (&mut self) are functions that can be called if they have &mut access to their environment
  • Fn (&self) are functions that can be called if they only have & access to their environment

A closure |...| ... will automatically implement as many of those as it can.

  • All closures implement FnOnce: a closure that can't be called once doesn't deserve the name. Note that if a closure only implements FnOnce, it can be called only once.
  • Closures that don't move out of their captures implement FnMut, allowing them to be called more than once (if there is unaliased access to the function object).
  • Closures that don't need unique/mutable access to their captures implement Fn, allowing them to be called essentially everywhere.

These restrictions follow directly from the type of self and the "desugaring" of closures into structs; described in my blog post Finding Closure in Rust.

For information on closures, see Closures: Anonymous Functions that Can Capture Their Environment in The Rust Programming Language.

like image 96
huon Avatar answered Sep 20 '22 05:09

huon