[Rust/러스트] 트레잇(trait) 정리

2022. 2. 25. 11:07Programming Language/Rust

반응형

■ 트레잇

트레잇은 타입들이 공통적으로 갖는 동작에 대해 추상화하도록 해줍니다. 이는 Java의 Interface에서 추상화 함수를 정의함으로써 강제력을 제공하는것과 유사합니다. 트레잇을 제네릭 파라미터의 타입으로 사용하는 상황에서 트레잇 바운드를 통해 서로 다른 구조체에 연관성을 제공할 수 있습니다.


◆ 트레잇 구현

Animal 트레잇 타입으로 구현한 Dog는 추상화된 custom_bark 메소드와 구현된 common_bark 메소드 두가지 메소드를 갖습니다. custom_bark 메소드는 Dog 구현부(impl)에서 강제적으로 정의가 되어야 하지만, common_bark 메소드는 정의하지 않고 Animal 트레잇 타입으로 구현한 모든 구조체에서 사용할 수 있습니다.

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 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 : 꾹꾹
반응형