Вектор объектов трейта в Rust
Когда в одном списке нужны разные структуры с одним трейтом, элементы описывают как коробки с объектом. Вектор тогда хранит одинаковый вид указателя на каждый элемент, а внутри лежат разные конкретные типы.
Соберем два значения в вектор и выведем оба приветствия:
trait Greet {
fn greet(&self) -> String;
}
struct User {
name: &'static str,
}
impl Greet for User {
fn greet(&self) -> String {
format!("hello, {}", self.name)
}
}
struct Bot {
id: i32,
}
impl Greet for Bot {
fn greet(&self) -> String {
format!("bot {}", self.id)
}
}
fn main() {
let a = User { name: "ann" };
let b = Bot { id: 2 };
let items: Vec<Box<dyn Greet>> = vec![Box::new(a), Box::new(b)];
for item in &items {
println!("{}", item.greet());
}
}
Переменная items владеет вектором
коробок. Цикл берет ссылку на каждый элемент
и вызывает greet без ветвления по
имени типа: достаточно общего трейта.
Тот же вектор можно передать в функцию, которая печатает каждый элемент:
trait Greet {
fn greet(&self) -> String;
}
struct User {
name: &'static str,
}
impl Greet for User {
fn greet(&self) -> String {
format!("hello, {}", self.name)
}
}
struct Bot {
id: i32,
}
impl Greet for Bot {
fn greet(&self) -> String {
format!("bot {}", self.id)
}
}
fn show_all(list: &[Box<dyn Greet>]) {
for item in list {
println!("{}", item.greet());
}
}
fn main() {
let a = User { name: "leo" };
let b = Bot { id: 5 };
let items: Vec<Box<dyn Greet>> = vec![Box::new(a), Box::new(b)];
show_all(&items);
}
Даны типы:
trait Greet {
fn greet(&self) -> String;
}
struct Cat {
name: &'static str,
}
struct Dog {
nick: &'static str,
}
Выполните Greet для обеих структур,
соберите вектор из двух коробок с объектами
и выведите оба приветствия в цикле.
Даны типы:
trait Score {
fn points(&self) -> i32;
}
struct Run {
value: i32,
}
struct Jump {
height: i32,
}
Реализуйте Score, положите по одному
значению каждого типа в вектор коробок
и выведите сумму очков.
Скажите, почему элементы такого вектора описывают коробкой, а не самим объектом без обертки.