Menu
CoddyTech

다중 제네릭 타입

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, 서로 다른 숫자 타입의 좌표, 또는 메타데이터와 연결된 결과처럼 서로 관련되어 있지만 잠재적으로 서로 다를 수 있는 두 데이터 조각을 연결해야 할 때 흔히 사용됩니다.

challenge icon

챌린지

쉬움

여러 generic type의 강력한 기능을 보여 주는 key-value 저장 시스템을 만들어 봅시다! 두 가지 type을 서로 연결할 수 있는 KeyValue struct를 만들 것입니다. 이는 label을 data에 연결하거나, ID를 object에 연결하거나, 그 밖의 모든 조합에 적합합니다.

code를 두 파일에 나누어 구성합니다:

  • keyvalue.rs: K type의 두 private field인 key와 V type의 value를 갖는 public generic struct KeyValue<K, V>를 Define합니다. 이 struct를 다루기 위한 methods를 Implement합니다:
    • key와 value로부터 KeyValue를 creates하는 new associated function
    • key에 대한 reference를 returns하는 key method
    • value에 대한 reference를 returns하는 value method
    • current value를 새 값으로 replaces하는 set_value method
  • main.rs: module을 가져오고 동일한 struct Define이 서로 다른 type 조합에서 어떻게 작동하는지 보여 줍니다. multiple generic의 유연성을 보여 주기 위해 mixed type의 key-value pair를 Create합니다.

main file에서 다음 key-value pair를 Create하고 다룹니다:

  1. string key와 integer value를 갖는 pair (first input을 key로 사용하고, second input을 i32로 parsed하여 value로 사용)
  2. key와 value를 Print
  3. value를 새 integer로 Update (i32로 parsed한 third input)
  4. updated value를 Print
  5. integer key와 string value를 갖는 second pair를 Create (fourth input을 i32로 parsed하여 key로 사용하고, fifth input을 value로 사용)
  6. 이 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}" 형식으로 이 쌍의 키와 값을 출력합니다
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Rust 컴파일러