Принадлежні об’єкти трейтів
Раніше ми бачили, як об’єкти трейтів можна використовувати з посиланнями, наприклад, &dyn Pet. Однак, ми також можемо використовувати об’єкти трейтів з розумними вказівниками, такими як Box, щоб створити власний об’єкт трейту: 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!("Гав, мене звуть {}!", self.name) } } impl Pet for Cat { fn talk(&self) -> String { String::from("Мяу!") } } fn main() { let pets: Vec<Box<dyn Pet>> = vec![ Box::new(Cat { lives: 9 }), Box::new(Dog { name: String::from("Фідо"), age: 5 }), ]; for pet in pets { println!("Привіт, ви хто? {}", pet.talk()); } }
Розташування пам’яті після виділення pets:
This slide should take about 10 minutes. 
                    - Типи, що реалізують певний трейт, можуть бути різних розмірів. Це унеможливлює створення таких типів, як 
Vec<dyn Pet>у наведеному вище прикладі. dyn Pet— це спосіб повідомити компілятору про тип динамічного розміру, який реалізуєPet.- У прикладі 
petsрозміщується у стеку, а векторні дані - у купі. Два векторні елементи є жирними вказівниками:- Жирний вказівник - це вказівник подвійної ширини. Він складається з двох компонентів: вказівника на власне об’єкт і вказівника на таблицю віртуальних методів (vtable) для реалізації 
Petцього конкретного об’єкта. - Дані для 
Dogна ім’я Фідо - це поляnameтаage. ДляCatє полеlives. 
 - Жирний вказівник - це вказівник подвійної ширини. Він складається з двох компонентів: вказівника на власне об’єкт і вказівника на таблицю віртуальних методів (vtable) для реалізації 
 - Порівняйте ці результати в наведеному вище прикладі:
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>>());