Pin
Pin türü ve pinning kavramı, Rust asenkron ekosisteminin temel yapı taşlarından biridir
- Ancak
Pin, yaklaşılması zor ve yanlış anlaşılmaya açık unsurlardan biridir
- Bu yazı,
Pinin neyi başarmayı amaçladığını, nasıl ortaya çıktığını ve bugün hangi sorunlara sahip olduğunu açıklıyor
Gereksinimler
- Asenkron fonksiyonlarda referansları desteklemek için
Future içinde referansların saklanması gerekiyordu
- Sorun, bu referansların self-referential olabilmesiydi
- Örnek kod:
async fn foo<'a>(z: &'a mut i32) { ... }
async fn bar(x: i32, y: i32) -> i32 {
let mut z = x + y;
foo(&mut z).await;
z
}
Barın iç durumu şu şekildedir:
enum Bar {
Start { x: i32, y: i32 },
FirstAwait { z: i32, foo: Foo<'?> },
Complete,
}
Pinin amacı, self-referential türleri güvenli şekilde işleyebilmektir
Çözüm olmayanlar: move constructor’lar ve offset pointer’lar
- Move constructor’lar ve offset pointer’lar Rust’ta çalışmaz
- Move constructor’lar taşıma sırasında pointer’ları günceller, ancak bu Rust’ta mümkün değildir
- Offset pointer’lar ise bir referansın self-referential olup olmadığının derleme zamanında bilinememesi nedeniyle çalışmaz
“Pinned typestate”
- Bir nesnenin her zaman taşınamaz olması değil, belirli bir andan itibaren taşınamaz olması gerekir
- Ralf Jung’un modelinde nesne, "owned" durumundan "shared" durumuna ve ardından "pinned" durumuna geçer
- Pinned duruma girdikten sonra nesne artık taşınamaz
?Move
Pinden önce, Move adlı yeni bir trait tabanlı çözüm denenmişti
Moveu implement etmeyen türler, referansları alındığında pinned duruma geçiyordu
- Ancak
Move geriye dönük uyumluluk sağlamıyordu
Pin
Pin, nesneleri pinned duruma getiren yeni bir referans türü tasarlar
Pin, kütüphane API’si olarak uygulanarak geriye dönük uyumluluğu korur
Unpin auto trait’i eklenerek çoğu türün pinned durum ile normal durum arasında ayrım yapmasına gerek kalmaz
Pin ile ilgili sorunlar
Pin, kullanılabilirlik açısından çeşitli sorunlara sahiptir
Pin, kütüphane türü olarak uygulandığı için normal referans türlerinin sahip olduğu birçok özelliği kaybeder
- Örneğin
&mut T, Copy implement etmese de aynı argüman olarak birden fazla kez geçirilebilir
Pin bu tür kolaylıkları sağlamaz
Pin kullanılırken çok fazla kafa karışıklığı yaşanır
Bir sonraki yazımda…
Pin, asenkron fonksiyonlarda keyfi referansların güvenli biçimde derlenebilmesini sağlar
- Ancak
Pin, karmaşıklığı artırır; bunu iyileştirmenin yolları bir sonraki yazıda ele alınacaktır
GN⁺ özeti
Pin, Rust asenkron ekosisteminin önemli bir bileşenidir
Pinin kullanılabilirlik sorunları, kütüphane türü olarak uygulanmasından kaynaklanır
Pini iyileştirme yolları bir sonraki yazıda ele alınacaktır
- Benzer işlevlere sahip projeler arasında
pin-project-lite bulunur
1 yorum
Hacker News görüşleri
Pin'in anlaşılmasının zor olmasının nedeni, resmi belgelerde açık şekilde anlatılmaması
Unpinolduğu için, Pin genellikle hiçbir işe yaramıyorTtiplerinin kümesi oldukça sıra dışı ve bu nokta belgelerde yeterince vurgulanmıyorPin'in zor olmasının nedeni, kendi başına bir anlam taşımaması
Pindurumunda, dil ya da standart kütüphane Pin'in ne yapıp ne yapamayacağını söylemiyorInnerTypesağlayıcısı pinned nesneleri işleyebilmek için ek (içsel olarak güvensiz) metotlar ve API'ler oluşturuyorPinyapısının tek amacı, daha az "yerleşik işlev" sunan bir işaretçi sağlamakBaşlığa "rust" eklenmeli ki yazının ne hakkında olduğu anlaşılsın
"value identity" terimi Mojo belgelerinde hiçbir yerde tanımlanmamış
Pin, teknik olarak doğru ama anlaşılması zor bir adın iyi bir örneği
immovable!(…)daha iyi olabilir, ama daha iyi bir ad bulmak da zorprevent_moving!(…)gibi daha açıklayıcı bir ad vePreventMovetrait'i daha iyi olabilirRust benzeri bir dilde move-constructor'lar olsaydı Pin'e olan ihtiyaç ortadan kalkabilirdi
&mutreferansı üzerindenmem::swap/replaceile nesneler taşınabiliyor, ancak buna gerçekten ihtiyaç duyulan durumlar nadirswapvereplaceişlemlerini unsafe yapmak sorunu çözebilirWithoutBoats, async iterator'lar, poll ve pin konularında aktif bir tartışma yürütüyor
Pinning/
!Move, async/await dışında da birçok kullanım için faydalı