rust trait

agnusdei·2025년 2월 5일

트레이트(Trait)란?

트레이트는 러스트에서 공통된 동작(메서드)을 정의하는 기능으로, 다른 언어의 인터페이스(interface)나 추상 클래스와 비슷합니다.

예를 들어, Summary라는 트레이트를 만들고 특정 타입(Tweet, NewsArticle 등)에 대해 이 트레이트를 구현하면, 해당 타입에서 Summary가 제공하는 메서드를 사용할 수 있습니다.


트레이트 구현 방법

트레이트를 정의하는 기본적인 문법은 다음과 같습니다:

pub trait Summary {
    fn summarize(&self) -> String;
}
  • trait Summary로 트레이트를 정의합니다.
  • 트레이트 안에는 메서드 시그니처(함수의 형태)만 작성하고, 구현은 하지 않습니다.

이제 Summary 트레이트를 특정 타입에 구현하려면 impl을 사용합니다:

pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}

impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("{}: {}", self.username, self.content)
    }
}
  • impl Summary for Tweet 형태로 Tweet 타입에 대해 Summary 트레이트를 구현했습니다.
  • summarize 메서드의 실제 동작을 정의해야 합니다.

트레이트 사용 방법

트레이트를 구현한 타입에서는 일반적인 메서드 호출처럼 사용할 수 있습니다.

fn main() {
    let tweet = Tweet {
        username: String::from("horse_ebooks"),
        content: String::from("of course, as you probably already know, people"),
        reply: false,
        retweet: false,
    };

    println!("1 new tweet: {}", tweet.summarize());
}

출력 결과:

1 new tweet: horse_ebooks: of course, as you probably already know, people
  • tweet.summarize()를 호출하면 Summary 트레이트에서 정의한 summarize 메서드가 실행됩니다.

트레이트 사용 시 주의할 점 (고아 규칙, Orphan Rule)

러스트에서는 임의의 타입에 대해 임의의 트레이트를 구현할 수 없습니다.

고아 규칙 (Orphan Rule)

  • 트레이트(Trait) 또는 타입(Type) 중 하나는 반드시 자신이 소유한 크레이트(라이브러리) 것이어야 합니다.
  • 즉, 외부 타입에 외부 트레이트를 구현할 수 없습니다.

✅ 가능: 자신이 만든 타입외부 트레이트 구현

use std::fmt;

struct MyType;

impl fmt::Display for MyType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "MyType 입니다!")
    }
}
  • MyType은 내가 만든 타입 → 표준 라이브러리의 Display 트레이트를 구현 가능

✅ 가능: 자신이 만든 트레이트외부 타입에 구현

trait MyTrait {
    fn my_method(&self) -> String;
}

impl MyTrait for Vec<i32> {
    fn my_method(&self) -> String {
        format!("이 벡터에는 {}개의 요소가 있습니다.", self.len())
    }
}
  • Vec<i32>는 외부 타입이지만, MyTrait은 내가 만든 트레이트 → 구현 가능

불가능: 외부 타입외부 트레이트 구현

// std::fmt::Display (외부 트레이트) 를 Vec<i32> (외부 타입) 에 구현하려고 하면 오류 발생
impl fmt::Display for Vec<i32> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}
  • Vec<i32>도 외부 타입, Display도 외부 트레이트 → 러스트에서 허용하지 않음
  • 만약 이런 것이 가능했다면, 같은 타입에 대해 여러 크레이트에서 다른 방식으로 구현될 수 있어 충돌 문제가 발생할 수 있음

트레이트 정리

  1. 트레이트(Trait)는 특정 타입이 공통적으로 가져야 할 메서드를 정의하는 기능이다.
  2. trait 트레이트명으로 정의하고, impl 트레이트 for 타입으로 구현한다.
  3. 트레이트를 사용하려면 use를 통해 스코프로 가져와야 한다.
  4. 고아 규칙(Orphan Rule) 때문에 외부 타입에 외부 트레이트를 구현할 수 없다.
  5. 트레이트를 활용하면 공통된 동작을 강제할 수 있어, 코드 재사용성과 유지보수성이 향상된다.
profile
DevSecOps, Pentest, Cloud(OpenStack), Develop, Data Engineering, AI-Agent

0개의 댓글