Objetos de Trait ProprietĂĄrios

Anteriormente vimos como objetos de trait podem ser usados com referĂȘncias, por exemplo, &dyn Pet. No entanto, tambĂ©m podemos usar objetos de trait com ponteiros inteligentes como Box para criar um objeto de trait owned: Box<dyn Pet>.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Layout da memĂłria apĂłs alocar pets:

<Dog as Pet>::talk<Cat as Pet>::talkPilhaHeappetsFidoptrtam2capacid.2dataname,4,4age5vtabledatalives9vtable

Speaker Notes

This slide should take about 10 minutes.
  • Tipos que implementam um dado trait podem ter tamanhos diferentes. Isto torna impossĂ­vel haver coisas como Vec<dyn Pet> no exemplo anterior.
  • dyn Pet Ă© uma maneira de dizer ao compilador sobre um tipo de tamanho dinĂąmico que implementa Pet.
  • No exemplo, pets Ă© alocado na pilha e os dados do vetor estĂŁo no heap. Os dois elementos do vetor sĂŁo fat pointers (ponteiros “gordos”):
    • Um fat pointer Ă© um ponteiro de dupla largura. Ele tem dois componentes: um ponteiro para o objeto real e um ponteiro para a tabela de mĂ©todos virtuais (vtable) para a implementação Pet desse objeto em particular.
    • Os dados para o Dog chamado Fido sĂŁo os campos name e age. O Cat tem um campo lives.
  • Compare estas saĂ­das no exemplo anterior::
    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>>());