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.


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 .


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.