CodeBlanks Logo Icon CodeBlanks

Özet - Trait nesneleri

Box<dyn Trait> ve vtable'ı birleştirerek bir şekil listesi yazarsın.

Trait nesneleri özeti

Trait nesnesi, veri işaretçisi ve vtable'dan oluşan şişman bir işaretçidir; &dyn T, &mut dyn T, Box<dyn T>, Rc<dyn T> biçimlerinde kullanılır. Karışık koleksiyonlar ve çalışma anı seçimleri için gereklidir; bedeli dolaylı çağrıdır. Trait'in dyn uyumlu olması gerekir; uyumsuz metotlar where Self: Sized ile hariç tutulur. Somut türe geri dönmek için std::any::Any ve downcast_ref kullanılır.

Any ile somut türe dönüş

dyn Any, 'static her türü tutabilen özel bir trait nesnesidir. Hangi tür olduğu çalışma anında sorgulanabilir:

use std::any::Any;

fn tanimla(o: &dyn Any) -> String {
    if let Some(n) = o.downcast_ref::<i32>() {
        format!("tamsayı {n}")
    } else if let Some(s) = o.downcast_ref::<&str>() {
        format!("metin: {s}")
    } else {
        String::from("bilinmeyen")
    }
}

Any, tasarımda son çaredir; çoğu zaman bir enum ya da trait metodu daha iyi bir çözümdür.

Uygulama Tür sorgusu

Yukarıdaki tanimla fonksiyonunu yaz. Vec<Box<dyn Any>> içinde 5, "metin" ve 2.5 tut; her biri için sonucu ayrı satıra yazdır.

Başlangıç kodu

main.rs
use std::any::Any;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::any::Any;

fn tanimla(o: &dyn Any) -> String {
    if let Some(n) = o.downcast_ref::<i32>() {
        format!("tamsayı {n}")
    } else if let Some(s) = o.downcast_ref::<&str>() {
        format!("metin: {s}")
    } else {
        String::from("bilinmeyen")
    }
}

fn main() {
    let ogeler: Vec<Box<dyn Any>> = vec![Box::new(5), Box::new("metin"), Box::new(2.5)];
    for o in &ogeler {
        println!("{}", tanimla(o.as_ref()));
    }
}

Beklenen çıktı

tamsayı 5
metin: metin
bilinmeyen

Soru ve cevaplar

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

1 <code>downcast_ref::&lt;T&gt;()</code> ne döndürür?

  • Panic verir
  • Box<T>
  • Değer gerçekten T ise Some(&T), değilse None Doğru cevap
  • Her zaman T

Açıklama: Any, türün kimliğini (TypeId) taşır; downcast bu kimliği karşılaştırır.

2 Türü sına

Soru
if let Some(n) = o.____::<i32>() {
    println!("tamsayı {n}");
}
Cevap
if let Some(n) = o.downcast_ref::<i32>() {
    println!("tamsayı {n}");
}

Açıklama: downcast_ref değer o türdeyse referans verir.

3 Grubun özeti

Kavram Anlamı
vtable Metot tablosu
Box<dyn T> Sahip trait nesnesi
where Self: Sized dyn'den hariç
dyn Any Çalışma anı tür sorgusu

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