Özet - Trait nesneleri
- Rust kursu
- İleri seviye
- Ders 59/81
- 5 dk
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
use std::any::Any;
fn main() {
// buraya yaz
}Örnek çözüm
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::<T>()</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
if let Some(n) = o.____::<i32>() {
println!("tamsayı {n}");
}
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 |