Sahipli Özellik Nesneleri (Owned Trait Objects)
Daha önce özellik nesnelerinin (trait objects) referanslarla nasıl kullanılabileceğini görmüştük, örn. &dyn Pet. Ancak, sahip olunan (owned) bir özellik nesnesi oluşturmak için Box gibi akıllı göstericilerle de özellik nesnelerini kullanabiliriz: Box<dyn Pet>.
struct Dog { name: String, age: i8, } struct Cat { lives: i8, } trait Pet { fn talk(&self) -> String; } impl Pet for Dog { fn talk(&self) -> String { format!("Hav, benim adım {}!", self.name) } } impl Pet for Cat { fn talk(&self) -> String { String::from("Miyav!") } } fn main() { let pets: Vec<Box<dyn Pet>> = vec![ Box::new(Cat { lives: 9 }), Box::new(Dog { name: String::from("Fido"), age: 5 }), ]; for pet in pets { println!("Merhaba, nasılsın? {}", pet.talk()); } }
pets tahsis edildikten sonraki bellek düzeni:
This slide should take about 10 minutes.
- Belirli bir özelliği (trait) gerçekleştiren türler farklı boyutlarda olabilir. Bu, yukarıdaki örnekte
Vec<dyn Pet>gibi şeylere sahip olmayı imkansız kılar. dyn Pet, derleyiciyePet’i gerçekleştiren dinamik boyutlu bir tür hakkında bilgi vermenin bir yoludur.- Örnekte,
petsyığın (stack) üzerinde tahsis edilir ve vektör verisi dinamik bellektedir (heap). İki vektör elemanı genişletilmiş göstericilerdir (fat pointers):- Genişletilmiş bir gösterici (fat pointer), çift genişlikli bir göstericidir. İki bileşeni vardır: gerçek nesneye bir gösterici ve o belirli nesnenin
Petgerçekleştirmesi için sanal metot tablosuna (virtual method table) (vtable) bir gösterici. - Fido adındaki
Dogiçin veri,nameveagealanlarıdır.Cat’in birlivesalanı vardır.
- Genişletilmiş bir gösterici (fat pointer), çift genişlikli bir göstericidir. İki bileşeni vardır: gerçek nesneye bir gösterici ve o belirli nesnenin
- Yukarıdaki örnekte bu çıktıları karşılaştırın:
println!("{} {}", std::mem::size_of::<Dog>(), std::mem::size_of::<Cat>()); println!("{} {}", std::mem::size_of::<&Dog>(), std::mem::size_of::<&Cat>()); println!("{}", std::mem::size_of::<&dyn Pet>()); println!("{}", std::mem::size_of::<Box<dyn Pet>>());