다중 제네릭 타입
Coddy Rust 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 26번째.
때로는 하나의 제네릭 매개변수만으로는 충분하지 않습니다. 두 개의 값을 보유하는 구조체가 필요하고 그 값들의 타입이 서로 다를 수 있다면 어떻게 해야 할까요? Rust에서는 여러 제네릭 매개변수를 쉼표로 구분하여 사용할 수 있습니다.
다음은 서로 다른 타입일 수 있는 두 값을 담는 Pair 구조체입니다:
struct Pair<T, U> {
first: T,
second: U,
}
<T, U>는 서로 독립적인 두 개의 타입 매개변수를 선언합니다. 인스턴스를 생성할 때 T와 U는 같은 타입일 수도 있고 완전히 다른 타입일 수도 있습니다. 이는 여러분에게 달려 있습니다.
let both_ints = Pair { first: 10, second: 20 }; // T=i32, U=i32
let mixed = Pair { first: "hello", second: 3.14 }; // T=&str, U=f64
let reversed = Pair { first: 100, second: "world" }; // T=i32, U=&str
메서드를 Implement할 때는 impl 블록에 모든 generic 매개변수를 선언합니다:
impl<T, U> Pair<T, U> {
fn get_first(&self) -> &T {
&self.first
}
fn get_second(&self) -> &U {
&self.second
}
}
이 패턴은 key-value pair, 서로 다른 숫자 타입의 좌표, 또는 메타데이터와 연결된 결과처럼 서로 관련되어 있지만 잠재적으로 서로 다를 수 있는 두 데이터 조각을 연결해야 할 때 흔히 사용됩니다.
챌린지
쉬움여러 generic type의 강력한 기능을 보여 주는 key-value 저장 시스템을 만들어 봅시다! 두 가지 type을 서로 연결할 수 있는 KeyValue struct를 만들 것입니다. 이는 label을 data에 연결하거나, ID를 object에 연결하거나, 그 밖의 모든 조합에 적합합니다.
code를 두 파일에 나누어 구성합니다:
keyvalue.rs:Ktype의 두 private field인key와Vtype의value를 갖는 public generic structKeyValue<K, V>를 Define합니다. 이 struct를 다루기 위한 methods를 Implement합니다:- key와 value로부터
KeyValue를 creates하는newassociated function - key에 대한 reference를 returns하는
keymethod - value에 대한 reference를 returns하는
valuemethod - current value를 새 값으로 replaces하는
set_valuemethod
- key와 value로부터
main.rs: module을 가져오고 동일한 struct Define이 서로 다른 type 조합에서 어떻게 작동하는지 보여 줍니다. multiple generic의 유연성을 보여 주기 위해 mixed type의 key-value pair를 Create합니다.
main file에서 다음 key-value pair를 Create하고 다룹니다:
- string key와 integer value를 갖는 pair (first input을 key로 사용하고, second input을
i32로 parsed하여 value로 사용) - key와 value를 Print
- value를 새 integer로 Update (
i32로 parsed한 third input) - updated value를 Print
- integer key와 string value를 갖는 second pair를 Create (fourth input을
i32로 parsed하여 key로 사용하고, fifth input을 value로 사용) - 이 pair의 key와 value를 Print
출력은 다음 format을 따라야 합니다:
Key: {key}, Value: {value}
Updated value: {value}
Key: {key}, Value: {value}예를 들어 inputs가 name, 42, 100, 7, lucky인 경우:
Key: name, Value: 42
Updated value: 100
Key: 7, Value: lucky첫 번째 pair는 KeyValue<String, i32>를 사용하는 반면 second pair는 KeyValue<i32, String>를 사용한다는 점에 주목하세요. 동일한 struct이지만 서로 다른 type 조합입니다!
다섯 개의 inputs를 받습니다: string key, integer value, replacement integer, integer key, string value입니다.
직접 해보기
mod keyvalue;
use keyvalue::KeyValue;
fn main() {
// 다섯 개의 입력을 읽습니다
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let string_key = input1.trim().to_string();
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let int_value: i32 = input2.trim().parse().expect("Failed to parse");
let mut input3 = String::new();
std::io::stdin().read_line(&mut input3).expect("Failed to read line");
let replacement_int: i32 = input3.trim().parse().expect("Failed to parse");
let mut input4 = String::new();
std::io::stdin().read_line(&mut input4).expect("Failed to read line");
let int_key: i32 = input4.trim().parse().expect("Failed to parse");
let mut input5 = String::new();
std::io::stdin().read_line(&mut input5).expect("Failed to read line");
let string_value = input5.trim().to_string();
// TODO: string_key와 int_value를 사용하여 KeyValue<String, i32> 쌍을 생성합니다
// TODO: "Key: {key}, Value: {value}" 형식으로 키와 값을 출력합니다
// TODO: replacement_int로 set_value를 사용하여 값을 업데이트합니다
// TODO: Print the updated value in format: "Updated value: {value}"
// TODO: int_key와 string_value를 사용하여 KeyValue<i32, String> 쌍을 생성합니다
// TODO: "Key: {key}, Value: {value}" 형식으로 이 쌍의 키와 값을 출력합니다
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Rust 컴파일러