CodeBlanks Logo Icon CodeBlanks

İşaretleme

Index ile bir görevi tamamlandı olarak işaretlersin.

İşaretleme

Bir görevi tamamlandı işaretlemek için kimliğine göre bulup alanını değiştirmemiz gerekir. iter_mut().find(..) eşleşen ilk elemana &mut referansı Option içinde verir:

fn tamamla(&mut self, id: u32) -> bool {
    match self.gorevler.iter_mut().find(|g| g.id == id) {
        Some(g) => {
            g.bitti = true;
            true
        }
        None => false,
    }
}

Bulunamayan kimlik için false döndürmek, çağıranın kullanıcıya mesaj göstermesini sağlar.

if let ile kısaltma

Aynı metot if let ile daha kısa yazılabilir:

fn tamamla(&mut self, id: u32) -> bool {
    if let Some(g) = self.gorevler.iter_mut().find(|g| g.id == id) {
        g.bitti = true;
        return true;
    }
    false
}

Silme için de benzer bir yöntem kullanılır: self.gorevler.retain(|g| g.id != id); eşleşmeyenleri tutar.

Uygulama Görevi tamamla

Liste'ye ekle, tamamla ve listele metotlarını yaz. İki görev ekle ("Süt al", "Kod yaz"), önce tamamla(2) ve tamamla(9) sonuçlarını boşlukla yazdır, sonra listeyi göster.

Başlangıç kodu

main.rs
struct Gorev {
    id: u32,
    metin: String,
    bitti: bool,
}

struct Liste {
    gorevler: Vec<Gorev>,
    sonraki_id: u32,
}

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
struct Gorev {
    id: u32,
    metin: String,
    bitti: bool,
}

struct Liste {
    gorevler: Vec<Gorev>,
    sonraki_id: u32,
}

impl Liste {
    fn ekle(&mut self, metin: &str) -> u32 {
        self.sonraki_id += 1;
        self.gorevler.push(Gorev {
            id: self.sonraki_id,
            metin: metin.to_string(),
            bitti: false,
        });
        self.sonraki_id
    }
    fn tamamla(&mut self, id: u32) -> bool {
        match self.gorevler.iter_mut().find(|g| g.id == id) {
            Some(g) => {
                g.bitti = true;
                true
            }
            None => false,
        }
    }
    fn listele(&self) {
        for g in &self.gorevler {
            let isaret = if g.bitti { "x" } else { " " };
            println!("[{}] {}: {}", isaret, g.id, g.metin);
        }
    }
}

fn main() {
    let mut liste = Liste {
        gorevler: Vec::new(),
        sonraki_id: 0,
    };
    liste.ekle("Süt al");
    liste.ekle("Kod yaz");
    let a = liste.tamamla(2);
    let b = liste.tamamla(9);
    println!("{} {}", a, b);
    liste.listele();
}

Beklenen çıktı

true false
[ ] 1: Süt al
[x] 2: Kod yaz

Soru ve cevaplar

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

1 Neden <code>self.gorevler[id as usize]</code> kullanmadık?

  • İndeksleme Rust'ta yok
  • Daha yavaş olurdu
  • u32 indekslenemez
  • Kimlikler indeksle aynı değil (1'den başlıyor, silme olursa kayar) ve yanlış kimlik panic verir Doğru cevap

Açıklama: Kimliğe göre aramak hem doğru hem güvenli; find yoksa None döner, panic olmaz.

2 Değiştirilebilir arama

Soru
match self.gorevler.____().find(|g| g.id == id) {
    Some(g) => { g.bitti = true; true }
    None => false,
}
Cevap
match self.gorevler.iter_mut().find(|g| g.id == id) {
    Some(g) => { g.bitti = true; true }
    None => false,
}

Açıklama: Alanı değiştirebilmek için &mut veren iter_mut gerekir.

3 Yöntem ve sonucu

Kavram Anlamı
iter_mut().find(..) Option<&mut Gorev>
retain(|g| g.id != 2) 2 silinir
tamamla(9) false
gorevler[9] Panic

Başlangıç bölümündeki tüm dersler

16 Proje: Yapılacaklar listesi

  1. Görev modeli
  2. Ekleme
  3. Listeleme
  4. İşaretleme
  5. Komut okuma