Menu
Coddy logo textTech

기본 구현

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

지금까지 우리가 정의한 모든 트레이트 메서드는 단지 시그니처, 즉 본문이 없는 요구 사항일 뿐이었습니다. 하지만 트레이트를 구현하는 대부분의 타입이 동일한 로직을 사용한다면 어떨까요? 러스트에서는 트레이트 정의 내에서 직접 기본 구현을 제공할 수 있습니다.

메서드 시그니처를 세미콜론으로 끝내는 대신, 본문을 추가합니다:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

이제 Greet를 구현하는 모든 타입은 impl 블록 내에 어떠한 코드도 작성하지 않고도 이 메서드를 자동으로 갖게 됩니다:

struct Guest;

impl Greet for Guest {}

let visitor = Guest;
println!("{}", visitor.greet());  // 안녕하세요!

비어 있는 impl Greet for Guest {}는 트레이트가 이미 동작을 제공하기 때문에 유효합니다. 구조체는 단순히 트레이트를 "선택(opts in)"하고 기본 메서드를 추가 구현 없이 받게 됩니다.

이 패턴은 대부분의 경우에 적합한 공통 동작을 정의하고자 할 때 유용합니다. 다른 동작이 필요한 타입은 기본 구현을 오버라이드(재정의)할 수 있고(다음 섹션에서 학습합니다), 표준 동작을 그대로 사용하려는 타입은 코드를 중복해서 작성할 필요가 없습니다.

challenge icon

챌린지

쉬움

알림 시스템을 구축하면서 기본 구현(default implementations)의 강력함을 살펴봅시다! 여러분은 표준 동작을 즉시 제공하는 트레이트를 만들어, 타입들이 반복적인 코드를 작성하지 않고도 해당 기능을 선택하여 사용할 수 있도록 할 것입니다.

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

  • notifiable.rs: 기본 구현을 가진 notify(&self) -> String 메서드를 포함하는 공개(public) Notifiable 트레이트를 정의하세요. 기본값은 "You have a new notification!"을 반환해야 합니다. 이 트레이트를 구현하는 모든 타입은 impl 블록에 아무것도 작성하지 않아도 이 동작을 자동으로 물려받게 됩니다.
  • alerts.rs: 트레이트를 구현하는 두 개의 간단한 공개 유닛 구조체(unit structs)를 만드세요:
    • EmailAlert — 빈 impl 블록으로 Notifiable을 구현합니다 (기본 구현 사용)
    • SystemAlert — 마찬가지로 빈 impl 블록으로 Notifiable을 구현합니다 (기본 구현 사용)
    두 구조체 모두 메서드 본문을 작성하지 않고도 자동으로 기본 알림 메시지를 갖게 됩니다!
  • main.rs: 모듈들을 하나로 모으고 두 알림 타입이 어떻게 동일한 기본 동작을 공유하는지 보여주세요. 두 구조체의 인스턴스를 생성하고 각각의 notify 메서드를 호출하세요.

메인 파일에서 EmailAlertSystemAlert를 생성한 후, 각각의 알림 내용을 별도의 줄에 출력하세요.

출력 결과는 다음과 같아야 합니다:

You have a new notification!
You have a new notification!

두 타입 모두 동일한 출력을 생성하는 점에 주목하세요. 이것이 바로 기본 구현의 묘미입니다! 어떤 구조체도 notify 메서드를 위해 코드를 작성할 필요가 없었지만, 둘 다 완벽하게 작동하는 알림 기능을 갖게 되었습니다. 다음 레슨에서는 타입에 맞춤형 동작이 필요할 때 이러한 기본값을 재정의(override)하는 방법을 배우게 됩니다.

치트 시트

트레이트 메서드는 시그니처만 제공하는 대신 메서드 본문을 제공함으로써 기본 구현(default implementations)을 가질 수 있습니다:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

트레이트를 구현하는 타입은 코드를 작성하지 않고도 자동으로 기본 동작을 부여받습니다:

struct Guest;

impl Greet for Guest {}

let visitor = Guest;
println!("{}", visitor.greet());  // Hello there!

트레이트가 기본 구현을 제공하는 경우 빈 impl 블록을 사용할 수 있습니다. 이를 통해 타입은 반복 없이 공유된 동작을 선택적으로 사용할 수 있습니다.

직접 해보기

mod notifiable;
mod alerts;

use notifiable::Notifiable;
use alerts::{EmailAlert, SystemAlert};

fn main() {
    // TODO: EmailAlert의 인스턴스 생성
    
    // TODO: SystemAlert의 인스턴스 생성
    
    // TODO: EmailAlert의 알림 출력
    
    // TODO: SystemAlert의 알림 출력
}
quiz icon실력 점검

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

Object Oriented Programming의 모든 레슨