CodeBlanks Logo Icon CodeBlanks

Dışarıdan değiştirme

Immutable bir yapıda iç veriyi değiştirme yöntemini öğrenirsin.

Dışarıdan değiştirme

Bir trait metodu &self alıyorsa ve sen uygulamada durum tutman gerekiyorsa (örneğin testte gönderilen mesajları kaydetmek), trait imzasını değiştiremezsin. İç değiştirilebilirlik burada devreye girer:

trait Bildirici {
    fn bildir(&self, mesaj: &str);
}

struct Kayitci {
    mesajlar: RefCell<Vec<String>>,
}

impl Bildirici for Kayitci {
    fn bildir(&self, mesaj: &str) {
        self.mesajlar.borrow_mut().push(mesaj.to_string());
    }
}

Kullanan kod

Bildirimi kullanan kod yalnızca trait'i bilir ve &dyn Bildirici alır:

fn kota_denetle(b: &dyn Bildirici, yuzde: u32) {
    if yuzde > 90 {
        b.bildir(&format!("uyarı: {yuzde}"));
    }
}

let k = Kayitci { mesajlar: RefCell::new(Vec::new()) };
kota_denetle(&k, 95);
println!("{}", k.mesajlar.borrow().len());   // 1

Gerçek uygulamada Bildirici e-posta gönderir; testte Kayitci mesajları yalnızca saklar.

Uygulama Kayıt tutan bildirici

Yukarıdaki Bildirici, Kayitci ve kota_denetle kodunu yaz. Sırasıyla 95, 50 ve 99 ile çağır; kayıt sayısını ve ilk mesajı boşlukla yazdır.

Başlangıç kodu

main.rs
use std::cell::RefCell;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::cell::RefCell;

trait Bildirici {
    fn bildir(&self, mesaj: &str);
}

struct Kayitci {
    mesajlar: RefCell<Vec<String>>,
}

impl Bildirici for Kayitci {
    fn bildir(&self, mesaj: &str) {
        self.mesajlar.borrow_mut().push(mesaj.to_string());
    }
}

fn kota_denetle(b: &dyn Bildirici, yuzde: u32) {
    if yuzde > 90 {
        b.bildir(&format!("uyarı: {yuzde}"));
    }
}

fn main() {
    let k = Kayitci { mesajlar: RefCell::new(Vec::new()) };
    for y in [95, 50, 99] {
        kota_denetle(&k, y);
    }
    let m = k.mesajlar.borrow();
    println!("{} {}", m.len(), m[0]);
}

Beklenen çıktı

2 uyarı: 95

Soru ve cevaplar

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

1 Bu desen en çok nerede kullanılır?

  • Sabitlerde
  • Test sahteleri (mock) ve önbellek gibi gizli durum tutan yapılarda Doğru cevap
  • Her struct alanında
  • Thread havuzlarında

Açıklama: Dışarıdan bakınca değişmez görünen ama içeride kayıt tutan yapılar için uygundur.

2 Kaydı sakla

Soru
fn bildir(&self, mesaj: &str) {
    self.mesajlar.____().push(mesaj.to_string());
}
Cevap
fn bildir(&self, mesaj: &str) {
    self.mesajlar.borrow_mut().push(mesaj.to_string());
}

Açıklama: &self arkasında vektöre eklemek için borrow_mut gerekir.

3 Çağrı ve kayıt sayısı

Kavram Anlamı
kota_denetle(&k, 95) +1
kota_denetle(&k, 50) Değişmez
kota_denetle(&k, 91) +1 (sınırın üstü)
kota_denetle(&k, 90) Değişmez (sınırda)

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