Menu
Coddy logo textTech

제네릭 메서드

Coddy Rust 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 25번째.

제네릭 구조체는 어떤 타입이든 가질 수 있지만, 그 데이터와 상호작용하는 메서드가 없다면 그리 유용하지 않습니다. 제네릭 구조체에 대한 메서드를 정의하려면 impl 블록에서 특별한 구문이 필요합니다.

핵심은 impl 자체에 제네릭 매개변수를 선언하는 것입니다:

struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    fn get(&self) -> &T {
        &self.value
    }
}

Wrapper<T> 앞에 있는 impl<T>를 주목하세요. 이것은 T가 전체 구현 블록에 대한 제네릭 타입 매개변수임을 Rust에게 알려줍니다. 이 선언이 없으면 Rust는 T라는 이름의 구체적인 타입을 찾으려 시도하다가 실패하게 됩니다.

get 메서드는 래퍼가 보유한 모든 유형에 대한 참조인 &T를 반환합니다. 이는 T가 정수이든, 문자열이든, 다른 어떤 유형이든 상관없이 작동합니다:

let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };

println!("{}", num_wrapper.get());  // 100
println!("{}", text_wrapper.get()); // Rust

동일한 메서드 정의가 두 경우 모두에 작동합니다. 제네릭 T가 컴파일 타임에 각 구체적인 타입에 맞춰지기 때문입니다.

challenge icon

챌린지

쉬움

메서드를 사용하여 제네릭 컨테이너를 확장해 봅시다! 어떤 타입이든 담을 수 있고 그 내용물과 상호작용하는 메서드를 제공하는 Box 구조체(Rust의 표준 Box와 혼동하지 마세요)를 만들 것입니다.

코드는 두 개의 파일로 구성됩니다:

  • mybox.rs: T 타입의 비공개 필드 contents를 가진 MyBox<T>라는 공개 제네릭 구조체를 정의합니다. 이 구조체에 대해 다음 메서드들을 구현하세요:
    • 주어진 값으로 새로운 MyBox를 생성하는 new 연관 함수
    • 내용물에 대한 참조를 반환하는 peek 메서드 (&self 사용)
    • 새로운 값을 받아 현재 내용물을 교체하는 replace 메서드 (&mut self 사용)
  • main.rs: 모듈을 가져와서 서로 다른 타입으로 작동하는 제네릭 메서드를 시연합니다. 박스를 생성하고, 내용물을 훔쳐보고(peek), 값을 교체하여 메서드가 실제로 작동하는 모습을 보여줍니다.

제네릭 구조체에 메서드를 구현할 때의 핵심 문법을 기억하세요: MyBox<T> 앞에 impl<T>를 작성하여 Rust에게 T가 전체 구현 블록에 대한 제네릭 매개변수임을 알려야 합니다.

메인 파일에서 다음 과정을 통해 MyBox를 시연하세요:

  1. 정수(첫 번째 입력, i32로 파싱됨)로 박스를 생성합니다.
  2. 내용물을 훔쳐보고(peek) 값을 출력합니다.
  3. 내용물을 새로운 정수(두 번째 입력, i32로 파싱됨)로 교체합니다.
  4. 다시 훔쳐보며(peek) 업데이트된 값을 보여줍니다.
  5. 문자열(세 번째 입력)로 두 번째 박스를 생성합니다.
  6. 문자열 박스의 내용물을 훔쳐봅니다(peek).

출력은 다음 형식을 따라야 합니다:

Integer box contains: {value}
After replace: {value}
String box contains: {value}

예를 들어, 입력값이 10, 25, Rust인 경우:

Integer box contains: 10
After replace: 25
String box contains: Rust

초기 정수, 교체할 정수, 그리고 문자열 값까지 총 세 개의 입력을 받게 됩니다.

치트 시트

제네릭 구조체에 대한 메서드를 정의하려면, impl 블록에 제네릭 매개변수를 선언하세요:

struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    fn get(&self) -> &T {
        &self.value
    }
}

impl<T> 구문은 Rust에게 T가 전체 구현 블록에 대한 제네릭 타입 매개변수임을 알려줍니다. 이것이 없으면 Rust는 T라는 이름의 구체적인 타입을 찾으려고 할 것입니다.

메서드는 제네릭 타입에 대한 참조(&T)를 반환할 수 있으며, 이는 모든 구체적인 타입에 대해 작동합니다:

let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };

println!("{}", num_wrapper.get());  // 100
println!("{}", text_wrapper.get()); // Rust

직접 해보기

mod mybox;

use mybox::MyBox;

fn main() {
    // 입력 읽기
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let initial_int: i32 = input1.trim().parse().expect("Invalid integer");

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let replacement_int: i32 = input2.trim().parse().expect("Invalid integer");

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let string_value = input3.trim().to_string();

    // TODO: 초기 정수값으로 MyBox 생성
    
    // TODO: 내용을 확인하고 출력: "Integer box contains: {value}"
    
    // TODO: 내용을 교체용 정수값으로 변경
    
    // TODO: 다시 확인하고 출력: "After replace: {value}"
    
    // TODO: 문자열 값으로 두 번째 MyBox 생성
    
    // TODO: 문자열 박스를 확인하고 출력: "String box contains: {value}"
}
quiz icon실력 점검

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

Object Oriented Programming의 모든 레슨