2

I read chapter 13.01 of the Rust Book and there is this section that confuses me greatly. Excerpt (emphasis mine):

FnOnce consumes the variables it captures from its enclosing scope, known as the closure’s environment. To consume the captured variables, the closure must take ownership of these variables and move them into the closure when it is defined. The Once part of the name represents the fact that the closure can’t take ownership of the same variables more than once, so it can be called only once.

When you create a closure, Rust infers which trait to use based on how the closure uses the values from the environment. All closures implement FnOnce because they can all be called at least once. Closures that don’t move the captured variables also implement FnMut, and closures that don’t need mutable access to the captured variables also implement

Don't the highlighted sentences contradict one another? If Fn and FnMut closures can be called more than once, why do they inherit from FnOnce?

I understand how each trait works individually - it's this superposition of FnOnce plus {FnMut, Fn} that bugs me. Why haven't the FnMut and Fn traits been defined independently of FnOnce?

I read GitHub issue #1225 but that didn't clear up my confusion.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Paul Razvan Berg
  • 16,949
  • 9
  • 76
  • 114
  • If I accept a closure that I **will** only call once, but you give me a closure that **could** be called multiple times, would you want that to compile? That's the reason. – Shepmaster Dec 07 '20 at 15:53
  • 4
    One should twist the reasoning the other way around: traits provide _added_ behavior. If a type implements `FnOnce`, then a value of that type can be called like a function, once. `Fn` and `FnMut` _extend_ this capability, letting the value be called multiple times. – E_net4 Dec 07 '20 at 15:57
  • Whoah, thinking about this in terms of "added behaviour" makes a lot of sense. Thanks @E_net4downvoteseverything! – Paul Razvan Berg Dec 07 '20 at 16:00
  • The "twisting" also has to do with which perspective you are coming from. Do you think of the closure _implementing_ the trait or the item _receiving_ the trait? – Shepmaster Dec 07 '20 at 16:08
  • @Shepmaster I was thinking in terms of the former perspective, but now I like the latter more. – Paul Razvan Berg Dec 07 '20 at 17:38

0 Answers0