Ana içeriğe geç
Modül 6 · Ders 2 ders 2Kurstaki 12/14~15 min
Modül dersleri (2/2)

Akıllı İşaretçiler: Kutu ve Rc

Akıllı işaretçi, işaretçi gibi davranan ancak meta verilere ve ekstra yeteneklere (referans sayma veya otomatik bellek yönetimi gibi) sahip bir veri yapısıdır.

Rust'ta sıradan referanslar (& gibi) yalnızca verileri ödünç alır. Akıllı işaretçiler ise çoğunlukla işaret ettikleri verilerin sahibidir. Yaygın örnekler arasında String ve Vec<T> yer alır, ancak standart kitaplık başka özelleştirilmiş örnekler de sağlar.


Yığın Tahsisi için Kutu<T>

En basit akıllı işaretçi Box<T> olup verileri yığın yerine yığın üzerinde depolar. Yığın üzerinde yalnızca yığına ayrılmış verilere yönelik işaretçi kalır.

Esas olarak aşağıdaki durumlarda kullanılır:

  1. Derleme zamanında boyutu bilinemeyen bir türünüz olduğunda (özyinelemeli tür gibi) ve bu türdeki bir değeri tam boyut gerektiren bir bağlamda kullanmak istediğinizde.
  2. Büyük miktarda verinin sahipliğini kopyalamadan aktarmak istediğinizde.

Temel örnek:

Rust
fn main() {
    let b = Box::new(5); // allocates the value 5 on the heap
    println!("b = {}", *b); // dereferences with * to read the value
}

Özyinelemeli Türler ve Eksileri Listeleri

Özyinelemeli tür, tanımının bir parçası olarak kendisinin değerini içerebilen bir türdür. Rust'ın derleme zamanında bir türün tam boyutunu bilmesi gerekir. Özyinelemeli bir türün derinliği sonsuz olabileceğinden, bir Kutu (bir işaretçi olduğundan sabit bir boyuta sahiptir) kullanmadığınız sürece derleyici bir hata üretir:

Rust
enum List {
    Cons(i32, Box<List>),
    Nil,
}

Rc<T>: Referans Sayma

Tek bir değerin birden fazla sahibi olabileceği durumlar vardır. Rc<T> (Referans Sayımı) akıllı işaretçisi, değerin hala kullanımda olup olmadığını belirlemek için bir değere yapılan referansların sayısını takip eder. Sayım sıfıra düşerse kaynak güvenli bir şekilde serbest bırakılır.

[!NOT] Rc<T> yalnızca tek iş parçacıklı senaryolar için uygundur. Çok iş parçacıklı (eşzamanlı) senaryolar için Arc<T> (Atomik Referans Sayımı) kullanmanız gerekir.

Rust
use std::rc::Rc;

fn main() {
    let a = Rc::new(5);
    let b = Rc::clone(&a); // increments the reference count to 2
    println!("References: {}", Rc::strong_count(&a));
}

Kendin dene

Alıştırma 1: Kutuyla Yığın Tahsisi

Egzersiz#rust.m6.l2.e1
Denemeler: 0Yükleniyor…

Box::new kullanarak heap'e 42 değerinde bir tamsayı değeri tahsis edin ve bunu val adlı bir değişkene atayın. Daha sonra, Kutuda saklanan değeri * operatörüyle açıkça referansını kaldırarak yazdırın.

Düzenleyici yükleniyor…
İpucu göster

Değeri yığında saklamak için `let val = Box::new(42);` kullanın ve `println!` içindeki `*val` ile referansı kaldırın.

3 denemeden sonra çözüm mevcut

Alıştırma 2: Özyinelemeli Veri Yapısı (Eksileri Listesi)

Egzersiz#rust.m6.l2.e2
Denemeler: 0Yükleniyor…

İki değişken içeren List adlı özyinelemeli bir numaralandırma tanımlayın: Bir tuple'ı saran Cons (i32, Box<List>) ve listenin sonunu temsil eden Nil. Ana işlevde, 1 öğesini ve ardından Nil'i içeren bağlantılı bir liste oluşturun.

Düzenleyici yükleniyor…
İpucu göster

Numaralandırma, 'enum List { Cons(i32, Box<List>), Nil }' olarak bildirildi. Listeyi `List::Cons(1, Box::new(List::Nil))` ile oluşturun.

3 denemeden sonra çözüm mevcut

Alıştırma 3: Sahipliği Rc ile Paylaşmak

Egzersiz#rust.m6.l2.e3
Denemeler: 0Yükleniyor…

a değişkeninde 100 değerini içeren paylaşılan bir tamsayı oluşturmak için std::rc::Rc kullanın. Referansı Rc::clone kullanarak b değişkenine kopyalayın. Son olarak Rc::strong_count fonksiyonunu kullanarak aktif referansların sayısını yazdırın.

Düzenleyici yükleniyor…
İpucu göster

Değeri `Rc::new(100)` ile oluşturun. 'Rc::clone(&a)' ile klonlayın ve 'Rc::strong_count(&a)' ile sahip sayısını görüntüleyin.

3 denemeden sonra çözüm mevcut