Why closure writing to its context still implements traits FnOnce?

Viewed 101

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?

0 Answers
Related