Menu
Coddy logo textTech

트레이트 구현하기

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

이제 트레이트를 정의하는 방법을 알았으니, 구조체가 그 계약을 충족하도록 만드는 방법을 살펴보겠습니다. 트레이트를 구현하는 것은 추상적인 요구사항을 구체적인 동작과 연결합니다.

구문은 impl TraitName for StructName을 사용합니다:

trait Speak {
    fn speak(&self) -> String;
}

struct Dog {
    name: String,
}

impl Speak for Dog {
    fn speak(&self) -> String {
        format!("{} says: Woof!", self.name)
    }
}

impl Speak for Dog 블록은 Rust에게 DogSpeak 트레이트를 구현하고 있음을 알려줍니다. 내부에서 실제 메서드 본문을 제공합니다. 이곳이 개가 어떻게 말하는지를 정의하는 곳입니다.

여러 타입이 동일한 트레이트를 구현할 때 트레이트의 강력함이 분명해집니다:

struct Cat {
    name: String,
}

impl Speak for Cat {
    fn speak(&self) -> String {
        format!("{} says: Meow!", self.name)
    }
}

이제 DogCat 모두 Speak 기능을 공유하지만, 각각 고유한 구현을 제공합니다. 두 타입 모두에서 .speak()를 호출할 수 있습니다:

let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };

println!("{}", dog.speak());  // Rex가 말합니다: Woof!
println!("{}", cat.speak());  // Whiskers가 말합니다: Meow!

이것이 Rust 다형성의 기초입니다. 서로 다른 타입, 동일한 인터페이스, 고유한 동작들입니다.

challenge icon

챌린지

쉬움

서로 다른 타입에 대해 트레이트(trait)를 구현하여 트레이트를 실제로 활용해 봅시다! Describable 트레이트를 만들고 이를 두 개의 서로 다른 구조체에 구현하여, 각 구조체가 자신만의 고유한 설명을 제공하도록 할 것입니다.

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

  • describable.rs: describe(&self) -> String 메서드를 가진 공개(public) Describable 트레이트를 정의합니다.
  • items.rs: 트레이트를 구현하는 두 개의 공개 구조체를 생성합니다:
    • 공개 title 필드(String)를 가진 Book
    • 공개 name 필드(String)를 가진 Movie
    각 구조체는 자신만의 고유한 설명 형식을 사용하여 Describable을 구현해야 합니다.
  • main.rs: 모듈들을 하나로 모으고, 두 구조체의 인스턴스를 생성한 뒤, 각각의 describe 메서드를 호출하여 동일한 트레이트가 서로 다른 타입에 대해 어떻게 다른 출력을 생성하는지 보여줍니다.

Book은 자신을 Book: {title}로 설명해야 하며, Movie는 자신을 Film: {name}으로 설명해야 합니다. 각 타입이 동일한 규약을 따르면서도 각자 고유한 동작을 수행하는 방식에 주목하세요!

메인 파일에서 제공된 두 개의 입력을 사용하여 책과 영화를 생성한 다음, 각각의 설명을 별도의 줄에 출력하세요.

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

Book: {title}
Film: {name}

예를 들어, 입력값이 1984Inception인 경우:

Book: 1984
Film: Inception

책 제목과 영화 이름이라는 두 개의 입력을 받게 됩니다.

치트 시트

구조체에 트레이트(trait)를 구현하려면, impl TraitName for StructName 구문을 사용합니다:

trait Speak {
    fn speak(&self) -> String;
}

struct Dog {
    name: String,
}

impl Speak for Dog {
    fn speak(&self) -> String {
        format!("{} says: Woof!", self.name)
    }
}

여러 타입이 서로 다른 동작으로 동일한 트레이트를 구현할 수 있습니다:

struct Cat {
    name: String,
}

impl Speak for Cat {
    fn speak(&self) -> String {
        format!("{} says: Meow!", self.name)
    }
}

let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };

println!("{}", dog.speak());  // Rex says: Woof!
println!("{}", cat.speak());  // Whiskers says: Meow!

이를 통해 Rust에서 다형성(polymorphism)이 가능해집니다. 즉, 서로 다른 타입들이 고유한 구현을 가지면서 동일한 인터페이스를 공유할 수 있습니다.

직접 해보기

mod describable;
mod items;

use describable::Describable;
use items::{Book, Movie};

fn main() {
    // 입력 읽기
    let mut title = String::new();
    std::io::stdin().read_line(&mut title).expect("Failed to read line");
    let title = title.trim().to_string();
    
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Failed to read line");
    let name = name.trim().to_string();
    
    // TODO: 제목을 사용하여 Book 인스턴스 생성
    
    // TODO: 이름을 사용하여 Movie 인스턴스 생성
    
    // TODO: 책의 설명 출력
    
    // TODO: 영화의 설명 출력
}
quiz icon실력 점검

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

Object Oriented Programming의 모든 레슨