Menu
Coddy logo textTech

트레이트 경계 문법

Coddy Rust 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 40번째.

지금까지 트레이트를 정의하고 구조체에 구현하는 방법을 배웠습니다. 또한 유연한 코드를 작성하기 위해 제네릭을 사용해 보았습니다. 이제 이러한 개념을 결합할 시간입니다. 트레이트를 사용하여 제네릭 function이 accept할 수 있는 타입을 제한해 보겠습니다.

매개변수에서 특정 method를 호출해야 하는 generic function을 생각해 보세요. 아무런 제약이 없으면 Rust는 T type에 해당 method가 있다는 것을 보장할 수 없습니다:

fn print_info<T>(item: T) {
    println!("{}", item.summarize());  // 오류! T에는 summarize()가 없을 수 있습니다
}

해결책은 trait bound입니다. 제네릭 매개변수 뒤에 : TraitName을 추가하면 T가 해당 트레이트를 구현해야 한다는 것을 Rust에 알릴 수 있습니다.

trait Summary {
    fn summarize(&self) -> String;
}

fn print_info<T: Summary>(item: T) {
    println!("{}", item.summarize());  // 이제 Rust는 이 메서드가 존재한다는 것을 압니다
}

<T: Summary> 구문은 "T는 Summary를 implements하는 모든 타입이다"라는 의미로 읽힙니다. 이제 이 function은 필요한 동작을 갖는 타입만 accept합니다. Summary를 implements하지 않는 타입을 전달하려고 하면 컴파일러는 명확한 Error와 함께 이를 거부합니다.

이 패턴은 필요한 동작에 대한 접근 권한을 유지하면서도 generic 코드를 작성할 수 있게 해 주기 때문에 강력합니다. 여러분의 function은 유연하게 유지되며, any type과 함께 작동하지만, 필요한 동작을 제공하는 type만 사용할 수 있습니다.

challenge icon

챌린지

쉬움

trait bound를 사용하여 올바르게 형식이 지정된 메시지만 전송될 수 있도록 보장하는 알림 시스템을 만들어 봅시다! 특정 trait을 구현하는 모든 타입을 accept하는 generic function을 만들면서, trait bound가 generic parameter를 제한하는 방식을 보여 줍니다.

코드를 두 개의 파일로 구성합니다:

  • notification.rs: message이라는 method를 가진 public Notify trait을 정의합니다. 이 method는 &self를 받고 String을 returns합니다. 그런 다음 이 trait을 구현하는 두 개의 public struct를 만듭니다:
    • Email: public subject field(String)을 가집니다. 이 message method는 Email: {subject}를 returns해야 합니다.
    • SMS: public content field(String)을 가집니다. 이 message method는 SMS: {content}를 returns해야 합니다.
    마지막으로 Notify trait을 구현하는 모든 타입 T를 accept하는 public generic function send_notification을 만듭니다. 이 function은 item에서 message()를 calling한 result를 출력해야 합니다.
  • main.rs: notification module을 가져오고 제공된 inputs를 사용하여 EmailSMS instance를 각각 만듭니다. generic function이 Notify를 구현하는 모든 타입과 함께 작동한다는 것을 보여 주기 위해 각각에 send_notification을 calling합니다.

여기서 핵심은 send_notification이 자신이 받는 구체적인 타입을 알지 못한다는 점입니다. 해당 타입이 message를 생성할 수 있다는 것만 알고 있습니다. trait bound T: Notify는 이 기능을 보장합니다.

출력에는 두 알림이 모두 전송된 결과가 표시되어야 합니다:

Email: {subject}
SMS: {content}

예를 들어 inputs가 Meeting TomorrowOn my way!인 경우:

Email: Meeting Tomorrow
SMS: On my way!

두 개의 inputs를 받습니다. email subject와 SMS content입니다.

직접 해보기

mod notification;

use notification::{Email, SMS, send_notification};

fn main() {
    // 입력 읽기
    let mut subject = String::new();
    std::io::stdin().read_line(&mut subject).expect("Failed to read line");
    let subject = subject.trim().to_string();
    
    let mut content = String::new();
    std::io::stdin().read_line(&mut content).expect("Failed to read line");
    let content = content.trim().to_string();
    
    // TODO: subject로 Email 인스턴스 생성
    
    // TODO: content로 SMS 인스턴스 생성
    
    // TODO: email로 send_notification 호출
    
    // TODO: sms로 send_notification 호출
}
quiz icon실력 점검

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

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

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