«ژنریک» به شما امکان میدهد کدی بنویسید که با چندین نوع کار کند، بدون تکرار.
نوعهای ژنریک را با استفاده از پرانتزهای زاویهدار <T> تعریف کنید، که در آن T «جاینگهدارِ» هر نوعی است.
fn largest_list<T>(l1: Array<T>, l2: Array<T>) -> Array<T> {
if l1.len() > l2.len() {
l1
} else {
l2
}
}
Cairo برای مشخصکردن اینکه نوع ژنریک باید از چه عملیاتی پشتیبانی کند، به قیدهای trait نیاز دارد. میتوانید با + این قیدها را اضافه کنید:
fn process_data<T, +Drop<T>, +Copy<T>>(value: T) -> T {
// Function body
}
ساختارها هم میتوانند ژنریک باشند:
#[derive(Drop)]
struct Container<T> {
value: T,
}
traitها هم میتوانند ژنریک باشند تا با انواع مختلف کار کنند:
trait Processor<T> {
fn process(self: @T) -> ByteArray;
}
impl MyProcessor<T, +Drop<T>> of Processor<T> {
fn process(self: @T) -> ByteArray {
"processed"
}
}
توابع میتوانند پارامترهای ژنریک همراه با قیدهای trait بپذیرند تا با هر نوعی که trait لازم را پیادهسازی میکند کار کنند:
fn use_processor<T, +Processor<T>, +Drop<T>>(item: T) -> ByteArray {
item.process()
}
فرودگاه تازهی برلین شما را به عنوان توسعهدهنده در آزمایشگاه رباتهایش استخدام کرده است. آنها رباتهایی دستوپاگیر و تا حدی شبیه انسان دارند و میکوشند از آنها برای بهبود خدمات مشتریان استفاده کنند.
اولین وظیفهی شما در این کار، برنامهریزی ربات است تا پس از اسکن گذرنامهی مسافران در باجهی خودپذیرش، به آنها به زبان مادریشان سلام کند.
ربات به تواناییهایش افتخار میکند، پس همیشه اول میگوید به چه زبانی میتواند صحبت کند و بعد به آن شخص سلام میکند. برای مثال، اگر کسی گذرنامهی آلمانی اسکن کند، ربات این جمله را میگوید:
I can speak German: Hallo Dietrich!
باید کدتان را طوری ساختاردهی کنید که شما و دیگر توسعهدهندگان بتوانید بهراحتی زبانهای جدید اضافه کنید.
به عنوان اولین قدم، یک trait به نام Greeter با دو تابع تعریف کنید.
language_name که زبانی (یک ByteArray) را برمیگرداند که ربات با آن به بازدیدکننده سلام میکند.greet که اسم بازدیدکننده (یک ByteArray) را میپذیرد و پیام سلام را به زبانی مشخص (یک ByteArray) برمیگرداند.سپس، تابعی به نام say_hello پیادهسازی کنید که اسم بازدیدکننده و هر چیزی را که trait Greeter را پیادهسازی میکند میپذیرد و سلام موردنظر (یک ByteArray) را برمیگرداند.
برای مثال، تصور کنید یک پیادهسازی آلمانی از Greeter داریم که در آن language_name مقدار "German" و greet مقدار "Hallo {name}!" را برمیگرداند:
say_hello("Dietrich", germanGreeter)
// => "I can speak German: Hallo Dietrich!"
حالا کاری کنید که ربات برای کسانی که گذرنامهی ایتالیایی اسکن میکنند هم کار کند.
یک struct به نام Italian بسازید و آن دو تابع را پیادهسازی کنید تا trait Greeter را از وظیفهی ۱ برآورده کنید.
میتوانید با "Ciao {name}!" به کسی به زبان ایتالیایی سلام کنید.
پیش از آنکه کار امروز را تمام کنید، قرار است قابلیتی اضافه کنید که بتواند به فرانسوی به مردم سلام کند.
یک struct به نام French بسازید و آن دو تابع را پیادهسازی کنید تا trait Greeter را برآورده کنید.
میتوانید با "Bonjour {name}!" به کسی به زبان فرانسوی سلام کنید.