Quando una chiusura implementa Fn, FnMut e FnOnce?


114

Quali sono le condizioni specifiche per una chiusura a implementare la Fn, FnMute FnOncetratti?

Questo è:

  • Quando una chiusura non implementa il FnOncetratto?
  • Quando una chiusura non implementa il FnMuttratto?
  • Quando una chiusura non implementa il Fntratto?

Ad esempio, la modifica dello stato della chiusura sul suo corpo impedisce al compilatore di implementarla Fn.


11
Hai visto questo recente fantastico articolo sulle chiusure ?
Shepmaster

Risposte:


126

Ciascuno dei tratti rappresenta proprietà sempre più restrittive sulle chiusure / funzioni, indicate dalle firme del loro call_...metodo, e in particolare dal tipo di self:

  • FnOnce( self) sono funzioni che possono essere chiamate una volta
  • FnMut( &mut self) sono funzioni che possono essere chiamate se hanno &mutaccesso al loro ambiente
  • Fn( &self) sono funzioni che possono essere chiamate se hanno &accesso solo al loro ambiente

Una chiusura |...| ...ne implementerà automaticamente il maggior numero possibile.

  • Tutte le chiusure implementano FnOnce: una chiusura che non può essere chiamata una volta non merita il nome. Si noti che se una chiusura viene implementata solo FnOnce, può essere chiamata solo una volta.
  • Le chiusure che non escono dalle loro acquisizioni vengono implementate FnMut, consentendo loro di essere chiamate più di una volta (se vi è un accesso non equilibrato all'oggetto funzione).
  • Le chiusure che non richiedono un accesso univoco / modificabile alle loro acquisizioni implementano Fn, consentendo loro di essere chiamate essenzialmente ovunque.

Queste restrizioni selfderivano direttamente dal tipo e dalla "rimozione dello zucchero" delle chiusure in strutture; descritto nel mio post sul blog Finding Closure in Rust .

Per informazioni sulle chiusure, vedere Chiusure: funzioni anonime che possono acquisire il loro ambiente nel linguaggio di programmazione Rust .


Se una chiusura è implementata FnOnce, significa che può essere richiamata una sola volta?
nalply

@nalply, sì, solo una volta.
huon

9
Ho letto male il commento di nalply e mi ha causato un po 'di confusione. Futuri lettori, si prega di notare che ha detto "se una chiusura implementa soloFnOnce ".
sleeparrow

2
Dettagli di implementazione: ne implementerà automaticamente il maggior numero possibile. non è del tutto vero, li implementerà automaticamente se sembra essere necessario. È possibile rilevare un Fn-impl mancante per una chiusura utilizzata per un argomento FnMut utilizzando la specializzazione. Questo è bug github.com/rust-lang/rust/issues/26085
bluss
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.