Узагальнення дають змогу писати код, який працює з багатьма типами без дублювання. Визначати узагальнені типи можна за допомогою кутових дужок <T>, де T є заповнювачем для будь-якого типу.
fn largest_list<T>(l1: Array<T>, l2: Array<T>) -> Array<T> {
if l1.len() > l2.len() {
l1
} else {
l2
}
}
Cairo вимагає обмежень трейтів, щоб указати, які операції повинен підтримувати узагальнений тип.
Додати обмеження можна за допомогою синтаксису +:
fn process_data<T, +Drop<T>, +Copy<T>>(value: T) -> T {
// Function body
}
Структури також можуть бути узагальненими:
#[derive(Drop)]
struct Container<T> {
value: T,
}
Трейти теж можуть бути узагальненими, що дає їм змогу працювати з різними типами:
trait Processor<T> {
fn process(self: @T) -> ByteArray;
}
impl MyProcessor<T, +Drop<T>> of Processor<T> {
fn process(self: @T) -> ByteArray {
"processed"
}
}
Функції можуть приймати узагальнені параметри з обмеженнями трейтів, завдяки чому вони працюють з будь-яким типом, який реалізує потрібний трейт:
fn use_processor<T, +Processor<T>, +Drop<T>>(item: T) -> ByteArray {
item.process()
}
Новий аеропорт у Берліні найняв нас розробником до своєї лабораторії роботів. У них є незграбні, трохи схожі на людей роботи, яких вони намагаються використовувати, щоб покращити обслуговування клієнтів.
Наше перше завдання на цій роботі - запрограмувати робота, щоб він вітав людей їхньою рідною мовою після того, як вони відсканували свої паспорти на стійці самостійної реєстрації.
Робот пишається своїми здібностями, тож він завжди спершу скаже, якою мовою вміє говорити, а вже потім привітає людину. Наприклад, якщо хтось сканує німецький паспорт, робот скаже:
I can speak German: Hallo Dietrich!
Потрібно структурувати код так, щоб ми та інші розробники могли легко додавати мови.
Як перший крок визначте трейт Greeter з двома функціями.
language_name, яка повертає мову (ByteArray), яку робот використає, щоб привітати відвідувача.greet, яка приймає імʼя відвідувача (ByteArray) і повертає повідомлення-привітання певною мовою (ByteArray).Далі реалізуйте функцію say_hello, яка приймає імʼя відвідувача й щось, що реалізує трейт Greeter, і повертає потрібне привітання (ByteArray).
Наприклад, уявімо німецьку реалізацію Greeter, для якої language_name повертає "German", а greet повертає "Hallo {name}!":
say_hello("Dietrich", germanGreeter)
// => "I can speak German: Hallo Dietrich!"
Тепер зробімо так, щоб робот працював для людей, які сканують італійські паспорти.
Створіть структуру Italian і реалізуйте обидві функції, щоб виконати трейт Greeter із завдання 1.
Італійською можна привітатися так: "Ciao {name}!".
Перш ніж завершити роботу, потрібно додати можливість вітати людей французькою.
Створіть структуру French і реалізуйте обидві функції, щоб виконати трейт Greeter.
Французькою можна привітатися так: "Bonjour {name}!".
Зареєструйтеся на Exercism, щоб вивчати й опановувати Cairo, а також 25 концепцій68 вправ та справжнє наставництво від людей, і все це безкоштовно.