제네릭을 사용하면 여러 타입에서 동작하는 코드를 중복 없이 작성할 수 있어요.
제네릭 타입은 꺾쇠괄호 <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 트레이트를 정의해요.
ByteArray)를 반환하는 language_name
ByteArray)을 받아 특정 언어로 된 인사 메시지(ByteArray)를 반환하는 greet
다음으로, 방문객의 이름과 Greeter 트레이트를 구현한 무언가를 받아서 원하는 인사말(ByteArray)을 반환하는 say_hello 함수를 구현해요.
예를 들어, language_name이 "German"을 반환하고 greet이 "Hallo {name}!"을 반환하는 독일어 Greeter 구현을 상상해 봐요:
say_hello("Dietrich", germanGreeter)
// => "I can speak German: Hallo Dietrich!"
이제 이탈리아 여권을 스캔한 사람들에게도 로봇이 동작하게 만들어요.
Italian 구조체를 만들고 1번 과제의 Greeter 트레이트를 충족하도록 두 함수를 구현해요.
이탈리아어로는 "Ciao {name}!"라고 인사할 수 있어요.
오늘 일과를 끝내기 전에 프랑스어로 인사하는 기능을 추가해야 해요.
French 구조체를 만들고 Greeter 트레이트를 충족하도록 두 함수를 구현해요.
프랑스어로는 "Bonjour {name}!"라고 인사할 수 있어요.