하지만 Trait 객체는 데이터와 행위가 결합하므로 다른 언어에서 말하는 객체와 유사하다. 다만, 객체에 데이터를 추가할 수 없다는 점에서 Trait 객체는 다른 언어의 객체만큼 범용적이지 않다. Trait 객체의 목적은 공통된 행위에 대한 추상화를 제공하는것이다.
// Draw trait 객체의 정의
pub trait Draw {
fn draw(&self);
}
// components 필드를 같는 Screen구조체. components필드에는
// Draw trait를 구현하는 트레이트 객체의 벡터를 저장한다.
pub struct Screen {
pub components: Vec<Box<dyn Draw>>,
}
// 제네릭을 사용하면 한가지 타입에 대해서만 draw()를 실행하지만
// Box<dyn Draw>타입을 사용하면 여러 타입에 대응이 가능하다.
impl Screen {
pub fn run(&self) {
for component in self.components.iter() {
component.draw();
}
}
}
// trait 구현하기 예
pub struct Button {
pub width: u32,
pub height: u32,
pub label: String,
}
impl Draw for Button {
fn draw(&self) {
// code to actually draw a button
}
}
struct SelectBox {
width: u32,
height: u32,
options: Vec<String>,
}
impl Draw for SelectBox {
fn draw(&self) {
// code to actually draw a select box
}
}
// trait객체를 이용해 같은 trait를 구현하는 다른 값을 저장하기
fn main() {
let screen = Screen {
components: vec![
Box::new(SelectBox {
width: 75,
height: 10,
options: vec![
String::from("Yes"),
String::from("Maybe"),
String::from("No")
],
}),
Box::new(Button {
width: 50,
height: 10,
label: String::from("OK"),
}),
],
};
screen.run();
}