CodeBlanks Logo Icon CodeBlanks

Rc<RefCell<T>>

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

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

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
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

Soru
let ortak = Rc::new(____::new(Vec::new()));
Cevap
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ı

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