CodeBlanks Logo Icon CodeBlanks

Tembel değerlendirme

Iterator'ların tembel (lazy) doğasını öğrenirsin.

Tembel değerlendirme

Bağdaştırıcılar tembeldir: tüketen bir yöntem çağrılana kadar hiçbir şey hesaplanmaz. Bu yüzden derleyici, sonucu kullanılmayan bir map için "iterators are lazy and do nothing unless consumed" uyarısı verir:

let it = [1, 2, 3].iter().map(|x| {
    println!("işleniyor {x}");
    x * 10
});
println!("henüz yok");          // henüz hiçbir şey işlenmedi
let ilk: Vec<i32> = it.take(2).collect();   // yalnızca 1 ve 2 işlenir

Tembellik sayesinde sonsuz yineleyiciler bile güvenle kullanılır: (1..).map(|n| n * n).take(3).

Tembelliğin yararı

Zincirlenmiş bağdaştırıcılar ara koleksiyon oluşturmaz; her eleman tüm hattan tek tek geçer. Derleyici bu zinciri genellikle elle yazılmış bir döngü kadar hızlı koda dönüştürür (sıfır maliyetli soyutlama):

// ara Vec oluşmaz
let t: u64 = (1..=1_000_000u64)
    .filter(|n| n % 2 == 0)
    .map(|n| n * 3)
    .sum();

inspect(|x| ..), hattın ortasında değerleri görmek için hata ayıklamada kullanışlıdır.

Uygulama Tembel hat

Yukarıdaki örneği yaz: her elemanda işleniyor N yazdıran bir map oluştur, önce henüz yok yazdır, sonra take(2) ile topla ve vektörü yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
fn main() {
    let veri = [1, 2, 3];
    let it = veri.iter().map(|x| {
        println!("işleniyor {}", x);
        x * 10
    });
    println!("henüz yok");
    let ilk: Vec<i32> = it.take(2).collect();
    println!("{:?}", ilk);
}

Beklenen çıktı

henüz yok
işleniyor 1
işleniyor 2
[10, 20]

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>(1..).filter(|n| n % 7 == 0).next()</code> ne kadar iş yapar?

  • Sonsuza kadar döner
  • Tüm sayıları listeler
  • Derlenmez
  • Yalnızca 1'den 7'ye kadar dener ve Some(7) döner Doğru cevap

Açıklama: next yalnızca bir eleman ister; zincir ilk eşleşmede durur.

2 İlk birkaçını al

Soru
let ilk: Vec<i32> = it.____(2).collect();
Cevap
let ilk: Vec<i32> = it.take(2).collect();

Açıklama: take yalnızca ilk n elemanı ister; kalanı hiç işlenmez.

3 İfade ve davranış

Kavram Anlamı
v.iter().map(f); Hiçbir şey yapmaz
v.iter().map(f).count() f her elemanda çalışır
(1..).take(3) Sonsuzdan güvenli parça
inspect(|x| ..) Arada gözlem

Orta seviye bölümündeki tüm dersler