Pin
- Tipe
Pin dan konsep pinning adalah komponen dasar dalam ekosistem async Rust
- Namun,
Pin adalah salah satu elemen yang sulit dipahami dan mudah disalahartikan
- Artikel ini menjelaskan apa yang ingin dicapai
Pin, bagaimana konsep ini muncul, dan apa masalah Pin saat ini
Requirements
- Untuk mendukung referensi di fungsi async, perlu menyimpan referensi di dalam
Future
- Masalahnya, referensi tersebut bisa berupa referensi self-referential
- Contoh kode:
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
}
- Status internal
Bar adalah sebagai berikut:
enum Bar {
Start { x: i32, y: i32 },
FirstAwait { z: i32, foo: Foo<'?> },
Complete,
}
- Tujuan
Pin adalah memanipulasi tipe self-referential dengan aman
Non-solutions: move constructors and offset pointers
- Konstruktor pemindahan dan offset pointer tidak bekerja di Rust
- Konstruktor pemindahan memperbaiki pointer saat pemindahan terjadi, tetapi hal ini tidak mungkin di Rust
- Offset pointer tidak bekerja karena saat kompilasi tidak diketahui apakah suatu referensi bersifat self-referential atau tidak
The “pinned typestate”
- Objek tidak selalu tidak bisa dipindahkan, tetapi harus menjadi tidak bisa dipindahkan mulai dari titik tertentu
- Dalam model Ralf Jung, objek berpindah dari status "dimiliki" ke status "dibagikan", lalu ke status "terpin"
- Setelah masuk ke status terpin, objek tidak lagi bisa dipindahkan
?Move
- Sebelum
Pin, pernah dicoba solusi berbasis trait baru bernama Move
- Tipe yang tidak mengimplementasikan
Move akan berpindah ke status terpin saat diambil referensinya
- Namun,
Move tidak menyediakan kompatibilitas mundur
Pin
Pin merancang jenis referensi baru yang membuat objek masuk ke status terpin
Pin diimplementasikan sebagai API library sehingga kompatibilitas mundur tetap terjaga
- Trait otomatis
Unpin ditambahkan agar sebagian besar tipe tidak perlu membedakan status terpin dan status biasa
The problems with Pin
Pin memiliki berbagai masalah dari sisi usability
Pin diimplementasikan sebagai tipe library sehingga banyak kemampuan yang dimiliki tipe referensi biasa hilang
- Misalnya,
&mut T tidak mengimplementasikan Copy, tetapi tetap bisa diberikan sebagai argumen beberapa kali
Pin tidak menyediakan kemudahan seperti ini
- Banyak kebingungan muncul saat menggunakan
Pin
In my next post…
Pin memungkinkan referensi arbitrer di fungsi async dikompilasi dengan aman
- Namun,
Pin menambah kompleksitas, dan artikel berikutnya akan membahas cara memperbaikinya
Ringkasan GN⁺
Pin adalah komponen penting dalam ekosistem async Rust
- Masalah usability pada
Pin berasal dari implementasinya sebagai tipe library
- Cara untuk memperbaiki
Pin akan dibahas di artikel berikutnya
- Proyek dengan fungsi serupa antara lain
pin-project-lite
1 komentar
Komentar Hacker News
Alasan
Pinsulit dipahami adalah karena dokumentasi resminya tidak menjelaskannya dengan jelasPinmenjamin objek tidak akan pernah dipindahkan", tetapi ini sebenarnya tidak benarUnpin, jadiPinbiasanya tidak berperan apa-apaTtempatPinbenar-benar bekerja sangat khusus dan hal ini tidak cukup ditekankan dalam dokumentasiPinsulit karena pada dirinya sendiri tidak punya maknaPin, bahasa maupun standard library tidak memberi tahu apa yang bisa dan tidak bisa dilakukanPinInnerTypemembuat metode dan API tambahan (yang secara internal tidak aman) agar objek yang di-pin bisa dimanipulasiPinsendiri adalah menyediakan pointer dengan lebih sedikit "fungsi bawaan"Kata "rust" seharusnya ditambahkan ke judul agar pembaca tahu artikel ini membahas apa
Istilah "value identity" tidak didefinisikan di mana pun dalam dokumentasi Mojo
Pinadalah contoh bagus dari nama yang akurat secara teknis tetapi sulit dipahamiimmovable!(…)mungkin lebih baik, tetapi sulit memikirkan nama yang lebih bagusprevent_moving!(…)dan traitPreventMovemungkin lebih baikDalam bahasa yang mirip Rust, jika ada move-constructors, kebutuhan akan
Pinbisa hilangObjek bisa dipindahkan lewat referensi
&mutmenggunakanmem::swap/replace, tetapi kasus yang benar-benar membutuhkannya jarangswapdanreplacetidak aman mungkin bisa menyelesaikan masalah iniWithoutBoats sedang melakukan diskusi aktif tentang topik iterator asinkron,
poll, danpinPinning/
!Moveberguna untuk banyak hal selain async/await