Kapan closure mengimplementasikan Fn, FnMut dan FnOnce?

114

Apa kondisi spesifik untuk penutupan untuk mengimplementasikan sifat Fn, FnMutdan FnOnce?

Itu adalah:

  • Kapan closure tidak mengimplementasikan FnOncesifat tersebut?
  • Kapan closure tidak mengimplementasikan FnMutsifat tersebut?
  • Kapan closure tidak mengimplementasikan Fnsifat tersebut?

Misalnya, mutasi status closure pada tubuhnya membuat compiler tidak mengimplementasikannya Fn.

Denilson Amorim
sumber
11
Pernahkah Anda melihat artikel bagus baru - baru ini tentang penutupan ?
Shepmaster

Jawaban:

126

Ciri-ciri masing-masing mewakili semakin banyak sifat restriktif tentang closure / fungsi, yang ditunjukkan oleh tanda tangan call_...metode mereka , dan khususnya jenis self:

  • FnOnce( self) adalah fungsi yang bisa dipanggil sekali
  • FnMut( &mut self) adalah fungsi yang dapat dipanggil jika memiliki &mutakses ke lingkungannya
  • Fn( &self) adalah fungsi yang bisa dipanggil jika hanya memiliki &akses ke lingkungannya

Sebuah closure |...| ...akan secara otomatis mengimplementasikan sebanyak mungkin dari itu.

  • Implementasi semua closure FnOnce: closure yang tidak bisa dipanggil sekali tidak pantas diberi nama. Perhatikan bahwa jika closure hanya diimplementasikan FnOnce, ia hanya bisa dipanggil sekali.
  • Closure yang tidak keluar dari captures implementnya FnMut, memungkinkannya dipanggil lebih dari sekali (jika ada akses yang tidak dipisahkan ke objek fungsi).
  • Closure yang tidak memerlukan akses unik / dapat berubah ke implement captures-nya Fn, memungkinkannya untuk dipanggil di mana saja.

Pembatasan ini mengikuti langsung dari jenis selfdan "desugaring" closure ke dalam struct; dijelaskan dalam posting blog saya Menemukan Penutupan di Rust .

Untuk informasi tentang closure, lihat Closures: Anonymous Functions yang Dapat Menangkap Lingkungan Mereka dalam Bahasa Pemrograman Rust .

huon
sumber
Jika closure hanya diimplementasikan FnOnce, apakah ini berarti ia hanya bisa dipanggil sekali?
Nalply
@ nalply, ya, hanya sekali.
huon
9
Saya salah membaca komentar nalply dan itu membuat saya bingung. Pembaca masa depan, harap dicatat bahwa dia berkata "jika penutupan hanya diimplementasikan FnOnce".
sleeparrow
2
Detail implementasi: akan secara otomatis mengimplementasikan sebanyak mungkin. tidak sepenuhnya benar, ini akan mengimplementasikannya secara otomatis jika diperlukan. Anda dapat mendeteksi Fn-impl yang hilang untuk penutupan yang digunakan untuk argumen FnMut menggunakan spesialisasi. Ini adalah bug github.com/rust-lang/rust/issues/26085
bluss