트레이트 구현하기
Coddy Rust 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 30번째.
이제 trait를 정의하는 방법을 알았으니, struct가 그 계약을 충족하도록 만드는 방법을 살펴보겠습니다. 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)
}
}
impl Speak for Dog 블록은 Dog이 Speak 트레이트를 구현하고 있음을 Rust에 알려 줍니다. 블록 안에서는 실제 메서드 본문을 제공합니다. 여기서 개가 말하는 방식을 정의합니다.
여러 type이 동일한 트레이트를 구현할 때 트레이트의 강력함이 분명해집니다:
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
이제 Dog와 Cat은 모두 Speak 기능을 공유하지만, 각각 고유한 구현을 제공합니다. 두 타입 중 어느 쪽에도 .speak()을 호출할 수 있습니다:
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex가 말합니다: 멍멍!
println!("{}", cat.speak()); // Whiskers가 말합니다: 야옹!
이것은 Rust에서 다형성의 기초입니다. 서로 다른 타입, 동일한 인터페이스, 고유한 동작.
챌린지
쉬움서로 다른 타입에 trait를 구현하여 trait를 실제로 활용해 봅시다! Describable trait를 만들고 두 개의 서로 다른 struct에 구현하여, 각각 고유한 설명을 제공하도록 합니다.
코드를 세 개의 파일로 나누어 구성합니다:
describable.rs: 메서드describe(&self) -> String을 포함하는 publicDescribabletrait를 정의합니다.items.rs: trait를 구현하는 두 개의 public struct를 만듭니다:- public
titlefield(String)을 가진Book - public
namefield(String)을 가진Movie
Describable을 구현해야 합니다.- public
main.rs: 모듈을 하나로 모으고, 두 struct의 instance를 만든 다음describe메서드를 호출하여 동일한 trait가 서로 다른 타입에 대해 어떻게 서로 다른 출력을 생성하는지 보여 줍니다.
Book은 자신을 Book: {title}로 설명하고, Movie는 자신을 Film: {name}으로 설명해야 합니다. 각 타입이 동일한 계약을 충족하면서도 고유한 동작을 제공하는 방식에 주목하세요!
main 파일에서 제공된 두 입력을 사용하여 book과 movie를 만든 다음, 각각의 설명을 별도의 줄에 출력합니다.
출력은 다음 형식을 따라야 합니다:
Book: {title}
Film: {name}예를 들어 입력이 1984와 Inception인 경우:
Book: 1984
Film: Inception두 개의 입력, 즉 book title과 movie name을 받게 됩니다.
직접 해보기
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: title로 Book 인스턴스 생성
// TODO: name으로 Movie 인스턴스 생성
// TODO: book의 설명 출력
// TODO: movie의 설명 출력
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Rust 컴파일러