CodeBlanks Logo Icon CodeBlanks

Iterator adapter

Kendi Iterator uygulayan tipini yazarsın.

Bitirme görevi: iterator adapter

Kendi yineleyici bağdaştırıcını yaz: herhangi bir yineleyicinin elemanlarını birer atlayarak veren CiftAdim. Bağdaştırıcı, içteki yineleyiciyi sarar ve next'te ondan iki eleman çekip ilkini döndürür:

struct CiftAdim<I> {
    ic: I,
}

impl<I: Iterator> Iterator for CiftAdim<I> {
    type Item = I::Item;
    fn next(&mut self) -> Option<I::Item> {
        let x = self.ic.next();
        self.ic.next();     // birini atla
        x
    }
}

Uzantı trait'i

.cift_adim() diye zincire eklenebilmesi için bir uzantı trait'i yazılır ve tüm yineleyicilere genel olarak uygulanır:

trait CiftAdimExt: Iterator + Sized {
    fn cift_adim(self) -> CiftAdim<Self> {
        CiftAdim { ic: self }
    }
}

impl<I: Iterator> CiftAdimExt for I {}

let v: Vec<i32> = (1..=7).cift_adim().collect();   // [1, 3, 5, 7]

Standart kütüphanedeki step_by(2) aynı işi yapar; bu görev bağdaştırıcıların nasıl kurulduğunu gösterir.

Uygulama Kendi bağdaştırıcın

Yukarıdaki CiftAdim yapısını, Iterator uygulamasını ve CiftAdimExt uzantı trait'ini yaz. (1..=7).cift_adim() sonucunu vektöre, "abcdef".chars().cift_adim() sonucunu String'e topla ve boşlukla yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
struct CiftAdim<I> {
    ic: I,
}

impl<I: Iterator> Iterator for CiftAdim<I> {
    type Item = I::Item;
    fn next(&mut self) -> Option<I::Item> {
        let x = self.ic.next();
        self.ic.next();
        x
    }
}

trait CiftAdimExt: Iterator + Sized {
    fn cift_adim(self) -> CiftAdim<Self> {
        CiftAdim { ic: self }
    }
}

impl<I: Iterator> CiftAdimExt for I {}

fn main() {
    let v: Vec<i32> = (1..=7).cift_adim().collect();
    let s: String = "abcdef".chars().cift_adim().collect();
    println!("{:?} {}", v, s);
}

Beklenen çıktı

[1, 3, 5, 7] ace

Soru ve cevaplar

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

1 <code>type Item = I::Item;</code> ne anlama gelir?

  • Item her zaman i32'dir
  • I bir eleman türüdür
  • Derlenmez
  • Bağdaştırıcı, içteki yineleyiciyle aynı türde eleman üretir Doğru cevap

Açıklama: I::Item, I'nin Iterator uygulamasındaki ilişkili türdür; bağdaştırıcı onu aynen aktarır.

2 Genel uygulama

Soru
impl<I: ____> CiftAdimExt for I {}
Cevap
impl<I: Iterator> CiftAdimExt for I {}

Açıklama: Tüm yineleyiciler uzantı trait'ini kazanır.

3 Girdi ve cift_adim sonucu

Kavram Anlamı
1..=7 [1, 3, 5, 7]
"abcdef".chars() "ace"
1..=2 [1]
boş yineleyici []

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