트레잇은 타입들이 공통적으로 갖는 동작
에 대해 추상화 해도록 해준다. 트레잇은 다른 언어들에서 인터페이스(interface)
라고 부르는 기능과 유사하지만, 몇 가지 다른 점이 있다.
trait는 상속과 달리 여러 개를
Mixin
할 수 있으며 인터페이스와 달리 구현부를 가질 수 있다. 상속과 인터페이스의 중간 쯤으로 생각할 수 있다. 또한 상속은 계층을 따라 좀 더 부모와 직접적인 관련이 있는 느낌이라면, 트레이트는 모듈화된 구현을 가져다 쓰는import
의 느낌이 강하다.
pub trait Summary {
fn summarize(&self) -> String;
}
일반 메소드를 실행하는 것과 매우 비슷하지만, impl
이후에, trait 이름을 적고 이후에 for
키워드와 구현하려는 유형의 이름을 지정하면 된다.
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
// Summary trait
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}
Default 값을 부여할 수 있다.
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
trait은 매개변수로 전달될 수 있다.
pub fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
제네릭 타입을 선언하여 여러개의 trait 매개변수를 보다 편리하게 표현할 수 있다.
pub fn notify<T: Summary>(item: &T, item2: &T) {
println!("Breaking news! {}", item.summarize());
println!("Breaking news! {}", item2.summarize());
}
fn
정의할 때, Display
와 Summary
impl
을 모두 정의할 수 있다.
pub fn notify(item: &(impl Summary + Display)) {
+
문법은 제네릭 타입의 trait 범위를 선언할 때도 유용하다.
pub fn notify<T: Summary + Display>(item: &T) {
fn some_function<T: Display + Clone, U: Clone + Debug>(t: &T, u: &U) -> i32 {
을 where
을 활용하여 아래와 같이 정의
fn some_function<T, U>(t: &T, u: &U) -> i32
where
T: Display + Clone,
U: Clone + Debug,
{