Box<T>

Box, dinamik bellek (heap) üzerindeki verilere sahip olunan (owned) bir göstericidir:

fn main() {
    let five = Box::new(5);
    println!("beş: {}", *five);
}
5StackHeapfive

Box<T>, Deref<Target = T> özelliğini (trait) gerçekleştirir (implement), bu da T’den metotları doğrudan bir Box<T> üzerinde çağırabileceğiniz anlamına gelir.

Özyinelemeli (recursive) veri türleri veya dinamik boyutlara sahip veri türleri, bir gösterici dolaylılığı (pointer indirection) olmadan satır içi (inline) olarak saklanamaz. Box bu dolaylılığı sağlar:

#[derive(Debug)]
enum List<T> {
    /// Boş olmayan bir liste: ilk eleman ve listenin geri kalanı.
    Element(T, Box<List<T>>),
    /// Boş bir liste.
    Nil,
}

fn main() {
    let list: List<i32> =
        List::Element(1, Box::new(List::Element(2, Box::new(List::Nil))));
    println!("{list:?}");
}
StackDinamikBelleklisteEleman1Eleman2YokHeapYıığn
This slide should take about 8 minutes.
  • Box, C++’daki std::unique_ptr’e benzer, ancak null olmaması garanti edilir.

  • Bir Box şu durumlarda yararlı olabilir:

    • boyutu derleme zamanında bilinemeyen bir türünüz varsa, ancak Rust derleyicisi tam bir boyut bilmek istiyorsa.
    • büyük miktarda verinin sahipliğini (ownership) aktarmak istiyorsanız. Yığın (stack) üzerinde büyük miktarda veri kopyalamaktan kaçınmak için, bunun yerine veriyi dinamik bellekte (heap) bir Box içinde saklayın, böylece sadece gösterici taşınır.
  • Box kullanılmasaydı ve bir List’i doğrudan List’e gömmeye çalışsaydık, derleyici bellekteki yapı (struct) için sabit bir boyut hesaplayamazdı (List sonsuz boyutta olurdu).

  • Box, normal bir göstericiyle aynı boyuta sahip olduğu ve dinamik bellekteki (heap) List’in bir sonraki elemanına işaret ettiği için bu sorunu çözer.

  • Liste tanımındaki Box’ı kaldırın ve derleyici hatasını gösterin. “dolaylılık olmadan özyinelemeli (recursive without indirection)” mesajını alırız, çünkü veri özyinelemesi için değeri doğrudan saklamak yerine dolaylılık, yani bir Box veya bir tür referans kullanmalıyız.

  • Box C++’daki std::unique_ptr’e benzese de, boş/null olamaz. Bu, Box’ı derleyicinin bazı enumların depolanmasını optimize etmesine olanak tanıyan türlerden biri yapar (“niş optimizasyonu”).