Rc<RefCell<T>>
- Rust kursu
- Orta seviye
- Ders 38/115
- 4 dk
Rc ve RefCell kombinasyonuyla birden çok sahibi olan değiştirilebilir veri öğrenirsin.
Rc<RefCell<T>>
Rc paylaşır ama değiştirmeye izin vermez; RefCell değiştirir ama paylaşmaz. Birleşimleri, birden çok sahibin değiştirebildiği veriyi verir:
use std::cell::RefCell;
use std::rc::Rc;
let ortak = Rc::new(RefCell::new(Vec::new()));
let a = Rc::clone(&ortak);
let b = Rc::clone(&ortak);
a.borrow_mut().push("a");
b.borrow_mut().push("b");
println!("{:?}", ortak.borrow()); // ["a", "b"]Ağaçlar, graflar, gözlemci listeleri gibi yapılarda sık kullanılır.
Döngü tehlikesi
İki Rc birbirini gösterirse sayaçları hiç sıfıra düşmez ve bellek sızar. Bunu önlemek için ters yöndeki bağlantı Weak ile tutulur; Weak sahiplik saymaz:
let ebeveyn = Rc::new(RefCell::new(String::from("kök")));
let zayif = Rc::downgrade(&ebeveyn);
if let Some(e) = zayif.upgrade() {
println!("{}", e.borrow()); // kök
}upgrade() değer hâlâ yaşıyorsa Some(Rc), bırakılmışsa None döndürür.
Uygulama Ortak liste
Rc::new(RefCell::new(Vec::new())) ile ortak bir liste oluştur ve iki kopya al (a, b). a üzerinden "a", b üzerinden "b" ekle. Listeyi ve sahip sayısını boşlukla yazdır.
Başlangıç kodu
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
// buraya yaz
}Örnek çözüm
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
let ortak = Rc::new(RefCell::new(Vec::new()));
let a = Rc::clone(&ortak);
let b = Rc::clone(&ortak);
a.borrow_mut().push("a");
b.borrow_mut().push("b");
println!("{:?} {}", ortak.borrow(), Rc::strong_count(&ortak));
}Beklenen çıktı
["a", "b"] 3
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Thread'ler arasında aynı işi görmek için hangi birleşim kullanılır?
- Rc<RefCell<T>>
- Box<RefCell<T>>
- Arc<RefCell<T>>
- Arc<Mutex<T>> Doğru cevap
Açıklama: RefCell Sync değildir; thread güvenli karşılıkları Mutex ve RwLock'tur.
2 Paylaşılan değiştirilebilir
let ortak = Rc::new(____::new(Vec::new()));
let ortak = Rc::new(RefCell::new(Vec::new()));
Açıklama: Rc paylaşımı, RefCell değiştirmeyi sağlar.
3 Tür ve yeteneği
| Kavram | Anlamı |
|---|---|
Rc<T> |
Paylaşım |
RefCell<T> |
İç değiştirme |
Rc<RefCell<T>> |
Paylaşımlı değiştirme |
Weak<T> |
Sahip olmayan bağlantı |