Rust'ta `fn () -> ()` nedir?
Ben Fn (sermaye-F) özelliklerin bir kavrayışa sahip: Fn, FnMut, FnOnce. Özellik olduklarını ve özellikler gibi çalıştıklarını anlıyorum.
Peki ya fn(küçük-f)? Editörlerde farklı bir renk alıyor, bu da bana bunun bir özellik olmadığını söylüyor. Diğer durumlarda benzer şekilde davranıyor gibi görünse de, diğerlerinin yapamadığı (ve tam tersi) bazı yerlerde de kullanılabilir. Bunu doğrudan belgelerde açıklayan hiçbir şey bulamadım.
Yanıtlar
prog-fh'nin cevabı esasen doğrudur, ancak bazı nüanslardan yoksundur. Rust'un üç tür işleve benzer türü vardır:
İşlev öğeleri , kullanarak bir işlev oluşturduğunuzda elde ettiğiniz şeylerdir
fn foo() {...}. Aynı zamanda, demet benzeri yapı veya enum varyantının yapıcısının türüdür. İşlev öğeleri sıfır boyuttadır (veri içermezler) ve genel olmayan her işlevin benzersiz, adlandırılamayan işlev öğesi türü vardır. Hata mesajlarında, derleyici bu "Voldemort türlerini"fn() -> () {foo}(işlevin adı ile{}) benzer şekilde görüntüler.Kapanışlar , işlev öğelerine benzer değerlerdir, ancak kapatmalar veri içerebilir: ortamlarından yakaladıkları değişkenlerin kopyaları veya referansları. Zaten bildiğiniz gibi, closure syntax (
|args| expression)kullanarak bir closure oluşturursunuz. İşlev öğeleri gibi, kapanışların da benzersiz, isimlendirilemeyen türleri vardır (derleyici tarafından böyle bir şekilde oluşturulur[closure@src/main.rs:4:11: 4:23]).İşlev işaretçileri , sorduğunuz şeydir: benzeyen türler
fn() -> (). İşlev işaretçileri veri içeremez, ancak sıfır boyutlu değildir; adlarından da anlaşılacağı gibi, bunlar işaretçilerdir. Bir işlev işaretçisi, ya bir işlev öğesini ya da hiçbir şey yakalayan bir kapanışı gösterebilir, ancak boş olamaz.
İşlev öğeleri ve kapanışlar, mümkün olduğunda otomatik olarak ilgili işlev işaretçisi türüne zorlanır, bu nedenle let f: fn(i32) = |_| ();işe yarar: Kapanış hiçbir şey yakalamadığı için, bir işlev işaretçisine zorlanabilir.
Her üç fonksiyon benzeri türleri alakalı uygulamak Fn, FnMutve FnOnceözellikleri (yani kapanışları hariç uygulamak olmayabilir Fnveya FnMutne yakalama bağlı olarak). Fonksiyon ürün ve fonksiyon işaretçileri de uygulamak Copy, Clone, Sendve Sync(bütün içerikleri yaptığınızda kapanışları sadece bu özellikleri uygulamak).
Performans açısından, işlev işaretçileri, jenerik ve özellik nesneleri arasında bir uzlaşma niteliğindedir. Çağrılmaları için başvurulmaları gerekir, bu nedenle bir işlev işaretçisini çağırmak, bir işlev öğesini veya kapatmayı doğrudan çağırmaktan daha yavaş olabilir, ancak yine dyn Fnde dolaylı çağrıya ek olarak bir vtable araması içeren bir özellik nesnesini çağırmaktan daha hızlı olabilir .
Referanslar
- Fn öğesi ve fn işaretçisi arasındaki pratik fark nedir?
- Neden benzersiz anonim türlere sahip bir dil tasarlayasınız?
- Null yapılabilir bir işlev işaretçisi içeren FFI için nasıl yapı oluşturabilirim?
- Bir işlev göstericisini kabul eden bir işlevi işleve kapatmak neden çalışmıyor?
Bir işlev işaretçi türüdür .
Kapanışın ihtiyaç duyduğu yakalanan ortamı değil, yalnızca işlevin adresini içerdiğinden, yalnızca bir işlevi ifade eder , bir kapatmayı değil.
Bir Fnözellik (büyük F) bir kapanışı veya bir işlevi ifade edebilir.
fn, bir işlev göstericisinin türüdür. Ayrıca dokümantasyonda buraya bakın:https://doc.rust-lang.org/std/primitive.fn.html