web-dev-qa-db-fra.com

Quand une fermeture met-elle en œuvre Fn, FnMut et FnOnce?

Quelles sont les conditions spécifiques pour une fermeture pour implémenter les traits Fn, FnMut et FnOnce?

C'est:

  • Quand une fermeture n'implémente-t-elle pas le trait FnOnce?
  • Quand une fermeture n'implémente-t-elle pas le trait FnMut?
  • Quand une fermeture n'implémente-t-elle pas le trait Fn?

Par exemple, la mutation de l'état de la fermeture sur son corps fait que le compilateur n'implémente pas Fn dessus.

86
Denilson Amorim

Les traits représentent chacun des propriétés de plus en plus restrictives sur les fermetures/fonctions, indiquées par les signatures de leurs call_... méthode, et notamment le type de self:

  • FnOnce (self) sont des fonctions qui peuvent être appelées une fois,
  • FnMut (&mut self) sont des fonctions qui peuvent être appelées si elles ont &mut accès à leur environnement
  • Fn (&self) sont des fonctions qui peuvent encore être appelées si elles n'ont que & accès à leur environnement.

Une fermeture |...| ... implémentera automatiquement autant de fichiers que possible.

  • Toutes les fermetures implémentent FnOnce: une fermeture qui ne peut pas être appelée une fois ne mérite pas son nom. Notez que si une fermeture implémente uniquement FnOnce, elle ne peut être appelée qu'une seule fois.
  • Les fermetures qui ne sortent pas de leurs captures implémentent FnMut, ce qui permet de les appeler plus d'une fois (s'il existe un accès sans biais à l'objet fonction).
  • Les fermetures qui n'ont pas besoin d'un accès unique/mutable à leurs captures implémentent Fn, ce qui permet de les appeler essentiellement partout.

Ces restrictions découlent directement du type de self et de la "suppression" des fermetures en structures (décrites dans Recherche de fermeture dans Rust ).

Pour plus d'informations sur les fermetures dans Rust à partir de 2017, consultez le chapitre Fermetures du livre Rust .

100
huon