STUDY/Rust

Rust - 24. 고급 기능 (2) 고급 트레이트, 고급 타입

sinawi95 2024. 3. 31. 14:28
728x90

너무 길어서 한번 끊음


1. 고급 트레이트

1.1. 연관 타입

트레이트 메서드를 정의할때 자리표시자 타입을 시그니처에서 사용할 수 있게 함.

  • 타입 자리 표시자와 트레이트를 연결함
  • 트레이트의 구현자는 자리표시자 타입 대신 구체적인 타입을 지정함
  • 제너릭과의 차이는 제너릭은 각 구현마다 타입을 명시해서 사용해야함. 
    • 타입을 여러 개 사용할수 있음
    • 연관 타입은 한 타입만 사용 가능함

1.2. 기본 타입 매개변수

  • 제너릭 타입 매개변수를 사용하면 제너릭 타입에 대한 구체적인 타입을 지정할수 있음
  • 연산자 오버로딩(std::ops)에 쓰임

1.3. 완전 정규화 문법 (fully qualified syntax)

같은 이름의 메서드 호출하기

trait Pilot {
    fn fly(&self);
}

trait Wizard {
    fn fly(&self);
}

struct Human;

impl Pilot for Human {
    fn fly(&self) {
        println!("This is your captain speaking.");
    }
}

impl Wizard for Human {
    fn fly(&self) {
        println!("Up!");
    }
}

impl Human {
    fn fly(&self) {
        println!("*waving arms furiously*");
    }
}

fn main() {
    let person = Human;
    Pilot::fly(&person);
    Wizard::fly(&person);
    person.fly();
}
  • self 매개변수가 있으면 타입 추론이 가능함.
  • Pilot::fly, Wizard::fly 처럼 명확하게 호출할수있음
trait Animal {
    fn baby_name() -> String;
}

struct Dog;

impl Dog {
    fn baby_name() -> String {
        String::from("Spot")
    }
}

impl Animal for Dog {
    fn baby_name() -> String {
        String::from("puppy")
    }
}

fn main() {
    println!("A baby dog is called a {}", Dog::baby_name());
    println!("A baby dog is called a {}", <Dog as Animal>::baby_name());
}

// output
// A baby dog is called a Spot
// A baby dog is called a puppy
  • self 매개변수가 없으면 어떤 타입을 의미하는지 알 수 없음
  • <Dog as Animal> 과같이 완전 정규화 문법을 사용해서 타입을 명시할 수 있음
    • <Type as Trait>::function(receiver_if_method, next_arg, ...);

1.4. 슈퍼트레이트 (supertrait)

슈퍼트레이트: 트레이트 정의가 의존하고 있는 트레이트

1.5. 뉴타입 패턴 (newtype pattern) 

기존 타입을 다른 구조체에서 얇게 감싸는 것. 튜플 구조체 사용

2. 고급 타입

2.1. 뉴타입 패턴

  • 값이 혼동되지 않도록 정적으로 강제하는 것, 값의 단위를 표시하는 것 등이 포함됨
  • 어떤 타입의 세부 사항에 대해서 추상화 가능.
  • 내부타입의 API와 다른 공개 API 노출 가능

2.2. 타입 별칭 (type alias)

fn main() {
    type Kilometers = i32;

    let x: i32 = 5;
    let y: Kilometers = 5;

    println!("x + y = {}", x + y);
}
  • c의 typedef 생각하면 될 듯
  • 긴 타입도 짧게 줄여서 사용가능

2.3. 부정 타입 (never type)

fn bar() -> ! {
    // --생략--
}
  • empty 타입이라고도 알려져있음
  • 함수가 값을 절대 반환하지 않음

2.4. 동적 크기 타입 (dynamically sized type) 

런타임에만 크기를 알수있는 값


https://doc.rust-kr.org/ch19-00-advanced-features.html

https://doc.rust-kr.org/ch19-03-advanced-traits.html