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