Rust 트레이트(Traits)는 공유 동작을 정의하는 인터페이스다. Go의 인터페이스, Haskell의 타입 클래스와 유사하지만, 기본 구현, 연산자 오버로딩, 제네릭 바운드 등 강력한 기능을 제공한다.
트레이트 정의와 구현
rust
trait Animal {
fn name(&self) -> &str;
fn sound(&self) -> String;
// 기본 구현
fn describe(&self) -> String {
format!("{}은 {}라고 울부짖는다", self.name(), self.sound())
}
}
struct Dog { name: String }
impl Animal for Dog {
fn name(&self) -> &str { &self.name }
fn sound(&self) -> String { "멍멍".to_string() }
// describe는 기본 구현 사용
}
트레이트 객체 vs 제네릭
rust
// 제네릭 (단형성화, 컴파일 시 결정)
fn notify<T: Animal>(item: &T) {
println!("{}", item.describe());
}
// 트레이트 객체 (동적 디스패치)
fn notify_dyn(item: &dyn Animal) {
println!("{}", item.describe());
}
// 박스 트레이트 객체
let animals: Vec<Box<dyn Animal>> = vec![
Box::new(Dog { name: "Rex".to_string() }),
];
연산자 오버로딩
rust
use std::ops::Add;
struct Vector2D { x: f64, y: f64 }
impl Add for Vector2D {
type Output = Vector2D;
fn add(self, other: Vector2D) -> Vector2D {
Vector2D { x: self.x + other.x, y: self.y + other.y }
}
}
let v = Vector2D { x: 1.0, y: 2.0 } + Vector2D { x: 3.0, y: 4.0 };
트레이트 바운드 조합
rust
use std::fmt::{Debug, Display};
fn print_info<T: Display + Debug + Clone>(item: T) {
println!("Display: {}", item);
println!("Debug: {:?}", item);
let _copy = item.clone();
}
// where 절 (복잡할 때)
fn compare<T>(a: T, b: T) -> bool
where T: PartialOrd + Debug
{
println!("Comparing {:?} and {:?}", a, b);
a < b
}
관련 개념