Dışarıdan değiştirme
- Rust kursu
- Orta seviye
- Ders 40/115
- 4 dk
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()); // 1Gerç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
use std::cell::RefCell;
fn main() {
// buraya yaz
}Örnek çözüm
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
fn bildir(&self, mesaj: &str) {
self.mesajlar.____().push(mesaj.to_string());
}
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) |