Box<T>
Box, dinamik bellek (heap) üzerindeki verilere sahip olunan (owned) bir göstericidir:
fn main() { let five = Box::new(5); println!("beş: {}", *five); }
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:?}"); }
-
Box, C++’dakistd::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
Boxiçinde saklayın, böylece sadece gösterici taşınır.
-
Boxkullanılmasaydı ve birList’i doğrudanList’e gömmeye çalışsaydık, derleyici bellekteki yapı (struct) için sabit bir boyut hesaplayamazdı (Listsonsuz 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 birBoxveya bir tür referans kullanmalıyız. -
BoxC++’dakistd::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”).