Dilimler (slice, [T] ve &[T] türleri), Rust'ta dizilerin, vektörlerin ve diğer eleman dizilerinin alt kümelerine güvenli ve etkili bir erişim sağlamak amacıyla tanıtılmıştır. Hafıza tahsisini ve veri kopyalamayı önleyerek, bir koleksiyonun bir bölümüne yalnızca "görünüm" veya pencere sağlamaktadır. Bu, derleme aşamasında boyutu sabit olan dizilerden ve bir işaretçi ve uzunluk saklayan ancak hafızayı elinde bulunduran dinamik koleksiyonlardan farklıdır.
Dillerde yaşam süresi kontrolünün sıkı olmadığı durumlarda diziler ve vektörlerle çalışırken genellikle sınır dışına çıkma (out of bounds), hafıza sızıntıları ve geçersiz işaretçilerin kullanımı gibi hatalar ortaya çıkar. Koleksiyonların alt kümeleriyle çalışırken kopyalama yapılmaması ve hafıza güvenliğinin kaybolmaması sağlanmalıdır ki bu özellikle sistem düzeyinde önemlidir.
Rust'ta dilim, içeriği elinde bulundurmayan "gösterici + uzunluk" şeklinde verilerin bir parçasına işaret eder. Her zaman bir yaşam süresi ile birlikte gelir ve derleyici dilimin orijinalinden (dizi, Vec, String) daha uzun yaşamayacağını garanti eder. Dilimle yapılan tüm işlemler, güvenli erişim yöntemleri aracılığıyla gerçekleştirilir ve sınır dışına çıkma durumları çalışma zamanında (runtime) panic ile sonuçlanır.
Kod Örneği:
let arr = [1, 2, 3, 4, 5]; let slice = &arr[1..4]; // [2,3,4] tür: &[i32] let mut vec = vec![10, 20, 30]; let mut_slice: &mut [i32] = &mut vec[..2]; mut_slice[0] = 99; assert_eq!(vec, [99, 20, 30]);
Anahtar Özellikler:
Orijinal dizinin veya vektörün boyutunu aşan bir dilim oluşturulabilir mi?
Hayır. Derleyici ve çalışma zamanı, dilimin yalnızca geçerli dizinlerde oluşturulabileceğini garanti eder. Sınır dışına çıkma girişimi panic ile sonuçlanır.
let arr = [1, 2, 3]; let s = &arr[0..4]; // çalışma zamanında panic
Dilimler hafızanın bağımsız sahipleri midir?
Hayır. Dilim yalnızca verilere bir "pencere"dir, hafızayı elinde bulundurmamaktadır. Eğer kaynak yerel ise bir fonksiyondan dilim döndürme girişimi derleme zamanı hatasına neden olur.
fn give_slice() -> &[i32] { let arr = [1,2,3]; &arr[1..] } // hata: arr yeterince uzun yaşamıyor
Dilimler ve Dizi arasındaki farklar nelerdir?
Dizi, derleme aşamasında bilinen sabit bir boyuta sahiptir ve tamamen stack'te yer alır. Dilim ise herhangi bir boyutta, dinamik olarak belirlenmiş olan ve her zaman bir işaretçi ve uzunluğu saklayan bir yapıdır.
let a: [u32; 3] = [1,2,3]; // Sabit boyutlu dizi let s: &[u32] = &a[..]; // Herhangi bir boyutta dilim
Programcı, fonksiyonda oluşturulmuş yerel bir diziden bir dilim döndürdü. Fonksiyon sonlandığında orijinal silindi ve dilim "sarkan" bir işaretçi oldu. Bu, bir hata yarattı ve hatta acil bir sonlanmaya neden oldu.
Artılar:
Eksiler:
Dilim, her zaman dış veriler üzerinde bir referans olarak oluşturulur. Veri sahipleri ve dilim aynı süre boyunca yaşar. Derleyici, dilim ile kaynak arasındaki yaşam süresi arasında sıkı bir ilişki garanti eder.
Artılar:
Eksiler: