Неизвестный конкретный тип у объекта в 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 show(item: &dyn Greet) {
let line = item.greet();
println!("{}", line);
}
fn main() {
let user: Box<dyn Greet> = Box::new(User { name: "ann" });
show(user.as_ref());
let bot: Box<dyn Greet> = Box::new(Bot { id: 2 });
show(bot.as_ref());
}
Функция show знает лишь про Greet.
Она не может обратиться к полю name
или id без отдельного согласования
типов, которое здесь не разбираем.
Тот же объект нельзя просто вернуть из функции как конкретную структуру: компилятор не знает, какой тип спрятан внутри. Работают ссылка на объект, коробка или вектор коробок, где в типе остается только трейт.
Даны типы:
trait Greet {
fn greet(&self) -> String;
}
struct Cat {
name: &'static str,
}
struct Dog {
nick: &'static str,
}
Реализуйте трейт для обеих структур, положите по одному значению в коробки с объектом и выведите приветствия через функцию с параметром-объектом.
Даны типы:
trait Label {
fn text(&self) -> &'static str;
}
struct Tag {
name: &'static str,
}
let boxed: Box<dyn Label> = Box::new(Tag { name: "go" });
Скажите, можно ли из boxed прочитать
поле name напрямую и почему.
Скажите, что теряется при переходе от конкретной структуры к объекту трейта и что при этом остается доступным.