2

I am confused. I have watched nearly all videos and official documentation on closures as well as a couple of unofficial, but still have difficulty predicting the behavior of the compiler.

Especially useful I've found this explanation and related article.

Particularly this:

  let mut b = "def".to_string();
  let closure_move_1 = move | mut a : String |
  {
     b.push( 'g' );
     a.push_str( &b );
     println!( "closureMove : {:?}", a );
     a
  };

  // try to uncomment
  // fn_once_1( closure_move_1 );
  // works
  // ? but why? routine write to its closure!

  // try to uncomment
  // fn_1( closure_move_1 );
  // ! this closure implements `FnMut`, not `Fn`
  // ? but why fn_once_1 works?

  // try to uncomment
  // fn_mut_1( closure_move_1 );
  // works as predicted

Here is a playground with source code. What did I miss?

Kos
  • 1,547
  • 14
  • 23
  • 3
    In the first question you linked, it says: "All closures implement `FnOnce`: a closure that can't be called once doesn't deserve the name." This is the behavior you are observing. `FnOnce` implies that a closure can be called *at least* once, not only once. – AlphaModder Jul 25 '21 at 06:14
  • 1
    This can be considered as a polymorphism, since `FnMut` and `Fn` types [implement](https://doc.rust-lang.org/std/ops/trait.FnOnce.html#implementors) `FnOnce` both can be used as `FnOnce`, same [relation](https://doc.rust-lang.org/src/core/ops/function.rs.html#242-249) exists between `Fn` and `FnMut`. – Ömer Erden Jul 25 '21 at 06:54

0 Answers0