Bir kapanış ne zaman Fn, FnMut ve FnOnce uygular?


114

Ne belirli koşullar bir kapatma uygulamak için Fn, FnMutve FnOnceözellikleri?

Yani:

  • Ne zaman bir kapatma yok değil uygulamak FnOnceözelliği?
  • Ne zaman bir kapatma yok değil uygulamak FnMutözelliği?
  • Ne zaman bir kapatma yok değil uygulamak Fnözelliği?

Örneğin, gövdesindeki kapanmanın durumunu değiştirmek, derleyicinin Fnüzerinde uygulanmamasına neden olur.


11
Kapanışlarla ilgili bu son harika makaleyi gördünüz mü ?
Shepmaster

Yanıtlar:


126

Özelliklerin her biri, call_...yöntemlerinin imzaları ve özellikle aşağıdakilerin türü ile gösterilen, kapanışlar / işlevler hakkında gittikçe daha kısıtlayıcı özellikleri temsil eder self:

  • FnOnce( self) bir kez çağrılabilen işlevlerdir
  • FnMut( &mut self) &mutortamlarına erişimleri varsa çağrılabilecek işlevlerdir
  • Fn( &self), yalnızca &ortamlarına erişimleri varsa çağrılabilen işlevlerdir

Bir kapatma |...| ..., olabildiğince çok sayıda otomatik olarak uygulayacaktır.

  • Tüm kapamalar uygulanır FnOnce: Bir kez çağrılamayan bir kapama adı hak etmiyor. Bir kapanış yalnızca uygularsa FnOnce, yalnızca bir kez çağrılabileceğini unutmayın.
  • FnMutYakalamalarından dışarı çıkmayan kapatmalar, birden fazla çağrılmalarına izin vererek uygulanır (işlev nesnesine diğerine sahip olmayan erişim varsa).
  • Yakalamalarına benzersiz / değiştirilebilir erişime ihtiyaç duymayan kapatmalar Fn, esasen her yerde çağrılmalarına izin vererek uygulanır .

Bu kısıtlamalar, doğrudan selfkapatma türünden ve yapıların "şekerinin kaldırılmasından" kaynaklanır; Rust'ta Kapanış Bulmak blog yazımda anlatıldı .

Kapanışları hakkında bilgi için, bkz Onların Çevre Yakalama Can Anonim Fonksiyonlar: Kapatmaları içinde Pas Programlama Dili .


Bir kapatma işlemi yalnızca uygulanıyorsa FnOnce, bu yalnızca bir kez çağrılabileceği anlamına mı gelir?
nalply

@nalply, evet, yalnızca bir kez.
huon

9
Nalply'nin yorumunu yanlış okudum ve kafamı karıştırdı. Gelecekteki okuyucular, lütfen "bir kapatma sadece uygularsa FnOnce" dediğini unutmayın .
sleeparrow

2
Uygulama ayrıntısı: Olabildiğince çoğunu otomatik olarak uygular. tam olarak doğru değil, ihtiyaç duyulduğunda bunları otomatik olarak uygulayacaktır. Uzmanlaşma kullanarak bir FnMut bağımsız değişkeni için kullanılan bir kapanış için eksik bir Fn impl algılayabilirsiniz. Bu hata github.com/rust-lang/rust/issues/26085
bluss
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.