泛型让你可以编写适用于多种类型、而无需重复的代码。
使用尖括号<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,它接受访客的姓名,以及任何实现了 Greeter trait 的对象,并返回所需的问候语(一个ByteArray)。
例如,假设有一个德语 Greeter 实现,它的 language_name 返回 "German",greet 返回 "Hallo {name}!":
say_hello("Dietrich", germanGreeter)
// => "I can speak German: Hallo Dietrich!"
现在让机器人为扫描意大利护照的人服务。
创建一个 struct Italian,实现那两个函数,从而满足任务 1 中的 Greeter trait。
你可以用"Ciao {name}!"来问候别人。
在下班之前,你还要加上用法语问候别人的功能。
创建一个 struct French,实现那两个函数,从而满足 Greeter trait。
你可以用"Bonjour {name}!"来问候别人。