Тип dyn Trait
Тип dyn Trait используется для динамической диспетчеризации методов трейта.
Он позволяет работать с значениями различных конкретных типов через общий интерфейс,
определённый трейтом. Запись dyn Trait практически всегда используется
вместе с указателем, например &dyn Trait или Box<dyn Trait>,
поскольку размер типа dyn Trait неизвестен на этапе компиляции.
Параметром здесь выступает сам трейт, который определяет набор методов, доступных через динамический тип. Компилятор создаёт таблицу виртуальных методов (vtable), которая позволяет во время выполнения находить нужную реализацию метода для конкретного типа.
Синтаксис
&dyn Trait
Box<dyn Trait>
&mut dyn Trait
Пример
Давайте создадим трейт Speak и реализуем его для двух типов,
а затем сохраним значения в векторе из Box<dyn Speak>:
trait Speak
{
fn speak(&self) -> String;
}
struct Dog;
struct Cat;
impl Speak for Dog
{
fn speak(&self) -> String
{
String::from("woof")
}
}
impl Speak for Cat
{
fn speak(&self) -> String
{
String::from("meow")
}
}
fn main()
{
let animals: Vec<Box<dyn Speak>> = vec![
Box::new(Dog),
Box::new(Cat),
];
for animal in &animals
{
println!("{}", animal.speak());
}
}
Результат выполнения кода:
"woof"
"meow"
Пример
Давайте передадим ссылку &dyn Speak в функцию,
чтобы продемонстрировать динамическую диспетчеризацию:
trait Speak
{
fn speak(&self) -> String;
}
struct Dog;
impl Speak for Dog
{
fn speak(&self) -> String
{
String::from("woof")
}
}
fn make_speak(s: &dyn Speak)
{
println!("{}", s.speak());
}
fn main()
{
let dog = Dog;
make_speak(&dog);
}
Результат выполнения кода:
"woof"
Смотрите также
-
тип
impl Trait,
который позволяет возвращать конкретный тип, реализующий трейт -
тип
fn,
который представляет собой указатель на функцию -
тип
reference,
который представляет собой ссылку на значение -
тип
PhantomData,
который используется для маркировки типов в обобщённом коде