CodeBlanks Logo Icon CodeBlanks

Closure ve iterator

Closure'ları iterator metotlarıyla kullanırsın.

Closure ve iterator

Closure'ların en yaygın kullanımı yineleyici yöntemleridir. Closure ortamdan değer yakalayabildiği için ölçütler dışarıdan verilebilir:

let esik = 50;
let notlar = vec![45, 72, 90, 38, 66];
let gecen: Vec<i32> = notlar
    .iter()
    .copied()
    .filter(|&n| n >= esik)     // esik yakalandı
    .collect();
println!("{:?}", gecen);       // [72, 90, 66]

copied(), &i32 elemanları i32'ye çevirir; böylece sonraki closure'larda çift referansla uğraşılmaz.

Fonksiyonu doğrudan vermek

Closure yerine adlı bir fonksiyon ya da metot da verilebilir; bu, kodu kısaltır:

fn cift_mi(n: &i32) -> bool { n % 2 == 0 }

let v = vec![1, 2, 3, 4];
let ciftler: Vec<&i32> = v.iter().filter(|n| cift_mi(n)).collect();
let metinler: Vec<String> = v.iter().map(ToString::to_string).collect();
println!("{:?} {:?}", ciftler, metinler);   // [2, 4] ["1", "2", "3", "4"]

Uygulama Geçenler

let esik = 50; ve vec![45, 72, 90, 38, 66] için eşiği geçen notları filter ile topla. Ardından her birine 5 ekleyen bir map ile ikinci bir vektör oluştur. İki vektörü boşlukla yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
fn main() {
    let esik = 50;
    let notlar = vec![45, 72, 90, 38, 66];
    let gecen: Vec<i32> = notlar.iter().copied().filter(|&n| n >= esik).collect();
    let artirilmis: Vec<i32> = gecen.iter().map(|n| n + 5).collect();
    println!("{:?} {:?}", gecen, artirilmis);
}

Beklenen çıktı

[72, 90, 66] [77, 95, 71]

Soru ve cevaplar

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

1 <code>.filter(|n| *n &gt; 2)</code> içinde <code>n</code> neden referanstır?

  • Tüm closure parametreleri referanstır
  • Bir hata
  • Yalnızca i32 için
  • filter elemanı tüketmeden bakmak için &Item verir Doğru cevap

Açıklama: filter elemanı korumak ya da atmak için yalnızca bakar; bu yüzden ödünç alır. .iter() ile birleşince &&i32 olur.

2 Ölçütle süz

Soru
let gecen: Vec<i32> = notlar.iter().copied().____(|&n| n >= esik).collect();
Cevap
let gecen: Vec<i32> = notlar.iter().copied().filter(|&n| n >= esik).collect();

Açıklama: filter closure true döndüren elemanları tutar.

3 Yöntem ve closure görevi

Kavram Anlamı
map(|x| ..) Dönüştürür
filter(|x| ..) Süzer
find(|x| ..) İlk eşleşen
any(|x| ..) En az biri mi?

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