CodeBlanks Logo Icon CodeBlanks

Box<dyn Trait>

Box<dyn Trait> ile sahipli trait nesnesi tutarsın.

Box<dyn Trait>

Box<dyn Trait>, sahip olunan bir trait nesnesidir: veri heap'te durur, kutu bırakılınca vtable'daki drop fonksiyonu çağrılır. Farklı türleri tek bir koleksiyonda tutmanın standart yoludur:

let hayvanlar: Vec<Box<dyn Ses>> = vec![Box::new(Kedi), Box::new(Kopek)];
for h in &hayvanlar {
    println!("{}", h.ses());
}

Fonksiyondan farklı türler döndürmek için de kullanılır: fn yeni_hayvan(tur: &str) -> Box<dyn Ses>.

Fabrika fonksiyonu

Çalışma anı bilgisine göre farklı türler üretmek, trait nesnesiz yapılamaz:

fn yeni_hayvan(tur: &str) -> Option<Box<dyn Ses>> {
    match tur {
        "kedi" => Some(Box::new(Kedi)),
        "kopek" => Some(Box::new(Kopek)),
        _ => None,
    }
}

Eklenti sistemleri, komut tabloları ve GUI bileşen ağaçları bu desenle kurulur.

Uygulama Hayvan fabrikası

Yukarıdaki yeni_hayvan fabrikasını yaz. ["kedi", "kopek", "kuş"] için oluşanların seslerini, None için tanınmadı yazdır.

Başlangıç kodu

main.rs
trait Ses {
    fn ses(&self) -> String;
}

struct Kedi;
struct Kopek;

impl Ses for Kedi {
    fn ses(&self) -> String {
        String::from("Miyav")
    }
}

impl Ses for Kopek {
    fn ses(&self) -> String {
        String::from("Hav")
    }
}

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
trait Ses {
    fn ses(&self) -> String;
}

struct Kedi;
struct Kopek;

impl Ses for Kedi {
    fn ses(&self) -> String {
        String::from("Miyav")
    }
}

impl Ses for Kopek {
    fn ses(&self) -> String {
        String::from("Hav")
    }
}

fn yeni_hayvan(tur: &str) -> Option<Box<dyn Ses>> {
    match tur {
        "kedi" => Some(Box::new(Kedi)),
        "kopek" => Some(Box::new(Kopek)),
        _ => None,
    }
}

fn main() {
    for t in ["kedi", "kopek", "kuş"] {
        match yeni_hayvan(t) {
            Some(h) => println!("{}", h.ses()),
            None => println!("tanınmadı"),
        }
    }
}

Beklenen çıktı

Miyav
Hav
tanınmadı

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>Box&lt;dyn Ses&gt;</code> thread'e gönderilecekse tür nasıl yazılmalıdır?

  • Arc<dyn Ses>
  • Gönderilemez
  • Box<dyn Ses + Send> Doğru cevap
  • Box<dyn Ses>

Açıklama: Trait nesnesi yalnızca adı geçen trait'leri taşır; Send gibi işaretçi trait'ler açıkça eklenir.

2 Sahip olunan nesne

Soru
let hayvanlar: Vec<____<dyn Ses>> = vec![Box::new(Kedi)];
Cevap
let hayvanlar: Vec<Box<dyn Ses>> = vec![Box::new(Kedi)];

Açıklama: Box<dyn Ses> trait nesnesini sahiplenir.

3 Tür ve özelliği

Kavram Anlamı
Box<dyn Ses> Sahip olunan
&dyn Ses Ödünç
Rc<dyn Ses> Paylaşılan
Box<dyn Ses + Send> Thread'e gönderilebilir

İleri seviye bölümündeki tüm dersler