Rust
Pin
Pin<T> ve self-referanslı verilerin önemini öğrenirsin.
Pin
Async fonksiyonların durum makineleri kendi içlerine referans tutabilir (örneğin .await öncesi alınan bir referans). Böyle bir değer bellekte taşınırsa içteki referans eski adresi gösterir. Pin<P>, gösterdiği değerin artık taşınmayacağını garanti eder; bu yüzden poll self: Pin<&mut Self> alır.
let f = async { 42 };
let mut kutulu = Box::pin(f); // heap'te sabitlendi
let mut yerel = std::pin::pin!(async { 1 }); // stack'te sabitlendi
Çoğu tür (i32, String, Vec) Unpin'dir: taşınmaları güvenlidir ve Pin onlar için bir kısıt getirmez.
Kutulu Future'lar
Pin<Box<dyn Future>> kendisi Unpin'dir ve Future uygular; bu yüzden doğrudan block_on'a verilebilir. Özyinelemeli async fonksiyonlar ve trait'lerden Future döndürmek de bu türle yapılır:
type KutuluFuture = Pin<Box<dyn Future<Output = i32>>>;
let isler: Vec<KutuluFuture> = vec![
Box::pin(async { 1 }),
Box::pin(async { 2 }),
];
let toplam: i32 = isler.into_iter().map(block_on).sum();
Uygulama Kutulu iş listesi
type KutuluFuture = Pin<Box<dyn Future<Output = i32>>>; tanımla. async { 1 } ve async { 2 } bloklarını Box::pin ile bir Vec<KutuluFuture>'e koy, her birini block_on ile çalıştırıp topla ve yazdır.
Örnek çözümü göster
use std::future::Future;
use std::pin::{pin, Pin};
use std::task::{Context, Poll, Waker};
fn block_on<F: Future>(f: F) -> F::Output {
let mut f = pin!(f);
let mut cx = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) {
return v;
}
}
}
type KutuluFuture = Pin<Box<dyn Future<Output = i32>>>;
fn main() {
let isler: Vec<KutuluFuture> = vec![Box::pin(async { 1 }), Box::pin(async { 2 })];
let toplam: i32 = isler.into_iter().map(block_on).sum();
println!("{}", toplam);
}
Kendini test et
-
Farklı async bloklardan oluşan bir listeyi tek bir <code>Vec</code>'te tutmak için hangi tür kullanılır?
- &dyn Future
- Pin<Box<dyn Future<Output = T>>>
- Vec<impl Future>
- Box<Future>
Cevabı göster
Pin<Box<dyn Future<Output = T>>> — Her async blok ayrı bir türdür; trait nesnesi ile ortak türe getirilir, Box::pin ile sabitlenir.
-
Heap'te sabitle
let mut kutulu = Box::____(async { 42 });
Cevabı göster
let mut kutulu = Box::pin(async { 42 });
-
Kavram ve anlamı
- Pin<P>
- Taşınmama garantisi
- Unpin
- Taşınması güvenli
- Box::pin
- Heap'te sabitler
- pin!
- Stack'te sabitler
Sıradaki ders: Özet - async/await