728x90
타입들이 공통적으로 갖는 동작에 대하여 추상화하도록 해줍니다. 러스트의 Trait은 java의 interface, python의 class기능과 유사합니다. trait을 제네릭 파라미터의 타입으로 사용하는 상황에서 trait bound를 통해 서로 다른 구조체에 연관성을 제공할 수 있습니다.
쉽게 말해 일종의 인터페이스로, 정의되지 않은 메서드의 선언들을 가질 수 있습니다.
Tait 구조
trait 트레잇명
{
선언들
}
트레잇은 impl 키워드를 통해서 구조체(클래스)에 구현됩니다.
impl 트레잇명 for 구조체명
{
구현들
}
Trait 구현
정적 메서드만 가지는 간단한 트레잇 소스입니다.
trait Foo{
fn foo();
}
struct Boom{
}
impl Foo for Boom{
fn foo(){
println!("foo");
}
}
fn main(){
Boom::foo();
}
foo
동적 메서드에서도 사용 가능합니다.
trait Foo{
fn foo(&self)->Self;
}
struct Boom{
}
impl Foo for Boom{
fn foo(&self)->Self{
println!("foo");
}
}
fn main(){
let obj = Boom();
let obj2 = obj.foo();
}
foo
Dog는 Animal tait 타입으로 구현(impl)했고 추상화된 custom_bark 메서드와 구현된 common_bark메서드 두가지를 갖습니다. custom_bark메서드는 Dog 구현부(impl)에서 강제적으로 정의가 되어야 하지만, common_bark메서드는 정의하지 않고 Animal trait타입으로 구현한 모든 구조체에서 사용할 수 있습니다.
trait Animal{
// 선언부만 정의
fn custom_bark(&self);
// 선언부,구현부 정의
fn common_bark(&self) {
println!("Common Bark");
}
}
struct Dog{
Pomeranian : String,
Poodle : String,
Dashshund : String,
}
impl Animal for Dog {
// common_bark 는 Animal 트레잇에서 구현되어 있기 때문에 Dog에서 따로 구현하지 않습니다.
fn custom_bark(&self){
println!("Pomeranian Bark : {}", self.Pomeranian);
println!("Poodle Bark : {}", self.Poodle);
println!("Dashshund Bark : {}", self.Dashshund);
}
}
fn main(){
let dog = Dog{
Pomeranian : String::from("낑낑"),
Poodle : String::from("멍멍"),
Dashshund : String::from("댕댕")
};
dog.common_bark();
dog.custom_bark();
}
Common Bark
Pomeranian Bark : 낑낑
Poodle Bark : 멍멍
Dashshund Bark : 댕댕
Trait Bound
트레잇 바운드는 서로 다른 구조체가 동일한 트레잇을 구현하고 있는상황에서 다른 구조체를 파라미터로 가질수 있습니다.
trait Animal{
// 선언문만 정의
fn custom_bark(&self);
// 선언문,구현문 정의
fn common_bark(&self) {
println!("Common Bark");
}
}
struct Dog{
Pomeranian : String,
Poodle : String,
Dashshund : String,
}
struct Cat{
Ragdoll : String,
RussianBlue : String,
Manx : String,
}
impl Animal for Dog {
// common_bark 는 Animal 트레잇에서 구현되어 있기 때문에 Dog에서 따로 구현하지 않습니다.
fn custom_bark(&self){
println!("Dog Bark");
println!("Pomeranian Bark : {}", self.Pomeranian);
println!("Poodle Bark : {}", self.Poodle);
println!("Dashshund Bark : {}", self.Dashshund);
}
}
impl Animal for Cat {
// common_bark 는 Animal 트레잇에서 구현되어 있기 때문에 Cat에서 따로 구현하지 않습니다.
fn custom_bark(&self){
println!("Cat Bark");
println!("Ragdoll Bark : {}", self.Ragdoll);
println!("RussianBlue Bark : {}", self.RussianBlue);
println!("Manx Bark : {}", self.Manx);
}
}
// 트레잇 바운드 예시 함수
fn animal_bark<T : Animal>(animal : T){
animal.custom_bark();
}
fn main(){
let dog = Dog{
Pomeranian : String::from("낑낑"),
Poodle : String::from("멍멍"),
Dashshund : String::from("댕댕")
};
let cat = Cat{
Ragdoll : String::from("냐옹"),
RussianBlue : String::from("캬악"),
Manx : String::from("꾹꾹")
};
animal_bark(dog);
animal_bark(cat);
}
Dog Bark
Pomeranian Bark : 낑낑
Poodle Bark : 멍멍
Dashshund Bark : 댕댕
Cat Bark
Ragdoll Bark : 냐옹
RussianBlue Bark : 캬악
Manx Bark : 꾹꾹
리턴 타입
리턴 타입으로 impl Trait 구문을 사용하면 특정 트레이트를 구현하고 있는 타입을 리턴하도록 할 수도 있습니다:
fn double(vector: Vec<i32>) -> impl Iterator<Item = i32> {
vector.into_iter().map(|x| x * 2)
}
fn main() {
for num in double(vec![1, 2, 3]) {
println!("{}", num);
}
}
'Rust' 카테고리의 다른 글
[Rust] ONNX모델로 detection (23) | 2023.07.02 |
---|---|
[Rust-Python] PyO3 (96) | 2023.06.30 |
Rust Generic 데이터 타입 (91) | 2023.06.19 |
Rust testing (142) | 2023.06.15 |
Rust 파이썬 바인딩 (56) | 2023.05.29 |