Параметр-объект трейта в 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 = User { name: "ann" };
let bot = Bot { id: 2 };
show(&user);
show(&bot);
}
Функция show не привязана к одной
структуре: ей достаточно метода greet.
Запись в параметре читается как ссылка на
объект трейта Greet, а не на
конкретный тип.
Тот же прием годится, когда результат нужно вернуть строкой, а не печатать сразу:
trait Greet {
fn greet(&self) -> String;
}
struct User {
name: &'static str,
}
impl Greet for User {
fn greet(&self) -> String {
format!("hello, {}", self.name)
}
}
fn line_for(item: &dyn Greet) -> String {
item.greet()
}
fn main() {
let user = User { name: "leo" };
let text = line_for(&user);
println!("{}", text);
}
Даны типы:
trait Greet {
fn greet(&self) -> String;
}
struct Cat {
name: &'static str,
}
let cat = Cat { name: "neo" };
Выполните набор для Cat, запишите
функцию с параметром-объектом по Greet,
которая печатает результат greet,
и передайте в нее ссылку на cat.
Даны типы:
trait Score {
fn points(&self) -> i32;
}
struct Run {
value: i32,
}
let run = Run { value: 40 };
Реализуйте Score для Run
и передайте ссылку на объект трейта в
функцию, которая выводит число очков.
Скажите, чем параметр-объект отличается от
записи с impl Greet в том же месте
сигнатуры.