dyn Trait
На додаток до використання трейтів для статичного пересилання за допомогою узагальнень, Rust також підтримує їх використання для динамічного пересилання зі стиранням типу за допомогою об’єктів трейтів:
Speaker Notes
This slide should take about 5 minutes.
-
Узагальнення, включаючи
impl Trait
, використовують мономорфізацію для створення спеціалізованого екземпляру функції для кожного окремого типу, який є екземпляром узагальнення. Це означає, що виклик методу трейта з узагальненої функції все ще використовує статичну диспетчеризацію, оскільки компілятор має повну інформацію про тип і може вирішити, яку саме реалізацію трейта типу слід використовувати. -
При використанні
dyn Trait
замість цього використовується динамічна диспетчеризація через віртуальну таблицю методів (vtable). Це означає, що існує єдина версіяfn dynamic
, яка використовується незалежно від того, який типPet
передано. -
При використанні
dyn Trait
об’єкт трейта повинен знаходитися за якимось посередником. У цьому випадку це буде посилання, хоча також можна використовувати розумні типи вказівників, такі якBox
(це буде продемонстровано у день 3). -
Під час виконання
&dyn Pet
представляється як “жирний вказівник”, тобто пара з двох вказівників: Один вказівник вказує на конкретний об’єкт, який реалізуєPet
, а інший вказує на таблицю vtable для реалізації трейту для цього типу. При виклику методуtalk
на&dyn Pet
компілятор шукає вказівник на функціюtalk
у таблиці vtable, а потім викликає цю функцію, передаючи вказівник наDog
абоCat
у цю функцію. Для цього компілятору не потрібно знати конкретний типPet
. -
dyn Trait
вважається “стертим типом”, оскільки під час компіляції ми більше не знаємо, яким є конкретний тип.