[0]
Rust는 객체 지향적인 언어 특성을 일부 갖고 있지만, 다른 객체 지향 언어와는 차이점도 상당히 많다. 그중 하나가 rust에서는 c++/java의 클래스처럼 코드를 포함하는 object가 존재하지 않는다는 것이다. 대신, Rust에서는 impl구문을 토해 struct 혹은 enum에 대한 메소드를 구현할 수 있다. impl 구문을 통해 trait을 구현하는 것도 가능한데, 이를 통해, Rust는 다형성(polymorphism)을 지원한다. 이글에선 trait에 대해 알아본다.
[1]
trait의 정의는 다음과 같이 할 수 있다.
// code from : https://doc.rust-lang.org/book
pub trait Summary {
fn summarize(&self) -> String;
}
trait은 다음과 같이 특정 struct 혹은 enum에 대해 구현할 수 있다.
// code from : https://doc.rust-lang.org/book
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)
}
}
또한 아래와 같이 default 구현을 만들어 놓을 수 있다. default를 그대로 사용하고자 한다면, impl 구문의 {]를 비워 두면 된다.
// code from : https://doc.rust-lang.org/book
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
//default implementation of Summary trait would be applied to tweet
impl tweet for Summary {}
이 외에도 다양한 활용법이 있지만, 가장 기본적인 활용은 위의 2가지라고 보면 된다. trait을 이용해서, 코드 중복을 피하면서, 가독성을 높이고 객체지향적인 프로그래밍을 할 수 있게 된다. trait의 조금 더 다양한 활용법은 공식 가이드를 참고하자.
[2]
Rust의 대부분의 기능과 마찬가지로, trait로 컴파일 타임에 구현된다. 컴파일 타임에 하나의 trait에 대해 어떤 타입으로 구현되어야 하는지 미리 알 수 있기 때문에, 실제 사용되는 타입들에 대한 trait만 컴파일 타임에 생성된다. 따라서 런타임 오버헤드가 존재하지 않는다.
[2]
trait의 java 등의 언어의 interface와 상당히 유사하다. 하지만 디자인 철학적인 부분에서 차이가 있는데, 다음의 사례를 통해 알아보자.
예컨대, animal interface에 move(), eat() 등의 메소드가 구현되어 있다고 생각하자. 이때, robot과 dog 클래스가 있을 경우, dog는 animal 이므로(dog is a animal) 상속받아서 구현하는데 아무런 문제가 없다. 하지만 robot은 animal이 아니고, eat()이란 동작을 하지 않기 때문에 상속이 불가능하다. 이런 경우 개발자는 울며 겨자 먹기로 move()를 복붙 할 수밖에 없다.
trait은 어떨까? 만약 trait을 위처럼 animal trait 하나로 만들고, 그 안에 move(), eat()의 메소드를 만들어 둔다면, 위와 같은 문제가 발생할 것이다. 하지만 trait 구현은 일반적으로 그렇지 않다. trait은 '공유 행동'을 보통 표현하게 되기 때문에, move trait과 eat trait을 각각 정의한다.
정리하자면, 개념상 interface는 카테고리(is-a)와 같고, trait은 tag(#move #eat)와 같다고 할 수 있다.
(이 부분 보충 필요...)
참고
https://www.reddit.com/r/rust/comments/cn20vu/traits_vs_interfaces/
https://doc.rust-lang.org/book/ch10-02-traits.html
'Computer Science > Rust' 카테고리의 다른 글
Rust의 async/await와 Future (0) | 2020.07.21 |
---|---|
Rust의 Copy trait와 Clone trait (2) | 2020.06.30 |
Rust의 스마트 포인터 (0) | 2020.05.20 |
Rust의 lifetime parameter (0) | 2020.05.05 |
Rust에서 null을 도입하지 않은 이유 (0) | 2020.01.17 |