Несколько трейтов у параметра в Rust
Параметр может требовать сразу два трейта. Тогда значение должно выполнить оба набора методов, и функция может вызывать действия из каждого. Ограничение записывают через знак плюс между именами трейтов.
Соберем подпись из заголовка и кода:
trait Greet {
fn greet(&self) -> String;
}
trait Label {
fn code(&self) -> i32;
}
struct User {
name: &'static str,
code: i32,
}
impl Greet for User {
fn greet(&self) -> String {
format!("hello, {}", self.name)
}
}
impl Label for User {
fn code(&self) -> i32 {
self.code
}
}
fn show(item: &impl Greet + Label) {
let line = item.greet();
let num = item.code();
println!("{} {}", line, num);
}
fn main() {
let user = User { name: "ann", code: 5 };
show(&user);
}
На экране фраза и число через пробел.
User выполняет оба трейта двумя
отдельными блоками, а show принимает
только те значения, где есть и greet,
и code.
Если одному типу не хватает второго набора,
такой аргумент в show не подойдет,
пока не допишут второй блок выполнения:
trait Greet {
fn greet(&self) -> String;
}
trait Label {
fn title(&self) -> &'static str;
}
struct Bot {
id: i32,
}
impl Greet for Bot {
fn greet(&self) -> String {
format!("bot {}", self.id)
}
}
impl Label for Bot {
fn title(&self) -> &'static str {
"svc"
}
}
fn caption(item: &impl Greet + Label) -> String {
format!("{}: {}", item.title(), item.greet())
}
fn main() {
let bot = Bot { id: 1 };
let line = caption(&bot);
println!("{}", line);
}
Дана структура:
struct Pack {
name: &'static str,
size: i32,
}
let pack = Pack { name: "a", size: 3 };
Объявите два набора: приветствие по name
и метод, возвращающий size. Выполните
оба для Pack и передайте ссылку
в функцию с двумя ограничениями, которая
печатает оба значения.
Дана структура:
struct Row {
key: i32,
title: &'static str,
}
let row = Row { key: 10, title: "top" };
Сделайте наборы для key и title,
выполните их для Row и верните одну
строку из функции с двумя требованиями.
Выведите ее.
Дана структура:
struct Unit {
id: i32,
label: &'static str,
}
let unit = Unit { id: 4, label: "x" };
Запишите два набора методов, выполните
их для Unit и вызовите функцию,
которая принимает &impl первого
и второго сразу. Напечатайте id
и label.