Rust'ta klasik bir çöp toplayıcı yoktur, bu nedenle karmaşık yapıların sahipliğini yönetmek için akıllı işaretçiler (smart pointers) kullanılır. En sık kullanılanlar şunlardır:
Box<T> — nesne için bellek ayırır ve sahipliği devreder. Derleme sırasında verilerin boyutu bilinmediğinde veya taşınabilir ama benzersiz bir kaynağa ihtiyaç duyulduğunda kullanılır.
Rc<T> (Referans Sayımlı) — referans sayımı yapar, birden fazla değişkenin değiştirilemez veriler üzerinde sahipliği "paylaşmasına" izin verir (sadece tek iş parçacıklı bağlamda).
Arc<T> (Atomik Referans Sayımlı) — aynı zamanda referans sayımı yapar, ancak atomiktir; çok iş parçacıklı programlarda kullanılabilir.
RefCell<T> — çalışma zamanında "içsel değiştirilebilir" sahiplik sağlar, değiştirilemez bir referans aracılığıyla bile içerikleri değiştirmeye izin verir, ancak sadece bir iş parçacığında (iş parçacığı güvenli değildir!).
Örnek:
use std::rc::Rc; let a = Rc::new(vec![1,2,3]); let b = Rc::clone(&a); // Artık hem a hem de b aynı verilere sahiptir
Tüm iş parçacıkları yalnızca verileri okursa, Rc<T> çok iş parçacıklı kodda kullanılabilir mi? Açıklayın.
Cevap: Hayır, kullanılamaz! Rc<T> yalnızca verilere değiştirilemez erişim sağlasa da, Rc<T> konteynerinin kendisi iş parçacığı güvenli değildir, çünkü içteki referans sayısı veri yarışlarına karşı korunmaz. Bunun için Arc<T> tasarlanmıştır — içteki sayacı iş parçacığı güvenlidir.
Örnek:
// Aşağıdaki kod derlenmeyecek! use std::thread; use std::rc::Rc; let five = Rc::new(5); for _ in 0..10 { let five = Rc::clone(&five); thread::spawn(move || { println!("{}", five); }); }
Hikaye
Hikaye
Hikaye
İş mantığı modülünde RefCell<T> kullanarak Arc<T> aracılığıyla iş parçacıkları arasında da iletilen verilere değiştirilebilir erişim sağlamaya çalıştık. Ancak RefCell<T> ile Arc<T> kombinasyonu yarışmalara ve çalıştırma sırasında paniğe yol açtı. İş parçacığı güvenli bir seçenek için RefCell<T> yerine Mutex<T> veya RwLock<T> kullanmak gerekir.