[rust] 제네릭 함수 런타임 처리

Rust는 컴파일 시간에 안정적이고 안전한 코드를 제공하면서도 제네릭을 지원하는 강력한 언어입니다. 그러나 때로는 런타임 시에 특정 타입에 대한 동작을 수행해야 하는 경우가 있습니다. 이럴 때는 어떻게 해야 할까요? 이 글에서는 Rust에서 제네릭 함수를 사용하여 런타임 시에 다른 타입들에 대해 다른 동작을 수행하는 방법을 알아보겠습니다.

동적 디스패치

Rust에서 제네릭 함수를 사용하여 런타임에 다른 동작을 수행하려면 동적 디스패치를 사용해야 합니다. 동적 디스패치는 런타임에 타입에 따라 다른 동작을 선택하는 메커니즘을 의미합니다.

트레이트 객체

동적 디스패치를 위해서는 트레이트 객체를 사용해야 합니다. 트레이트 객체는 트레이트를 구현한 구조체를 가리키는 런타임에서 결정되는 포인터입니다. 이를 통해 런타임에 다양한 타입의 구조체에 대한 동작을 수행할 수 있습니다.

trait MyTrait {
    fn action(&self);
}

struct Type1;
struct Type2;

impl MyTrait for Type1 {
    fn action(&self) {
        println!("Type1 action");
    }
}

impl MyTrait for Type2 {
    fn action(&self) {
        println!("Type2 action");
    }
}

fn perform_action(obj: &dyn MyTrait) {
    obj.action();
}

fn main() {
    let obj1 = Type1;
    let obj2 = Type2;

    perform_action(&obj1);
    perform_action(&obj2);
}

이 예제에서는 MyTrait 트레이트를 구현한 Type1Type2 구조체를 만들었습니다. 그리고 perform_action 함수를 사용하여 런타임에 트레이트 객체를 통해 동작을 수행하고 있습니다.

다른 타입에 대한 동작 수행하기

이제 제네릭 함수와 트레이트를 사용하여 런타임에 다른 타입에 대해 다른 동작을 수행하는 함수를 만들어 보겠습니다.

trait MyTrait {
    fn action(&self);
}

struct Type1;
struct Type2;

impl MyTrait for Type1 {
    fn action(&self) {
        println!("Type1 action");
    }
}

impl MyTrait for Type2 {
    fn action(&self) {
        println!("Type2 action");
    }
}

fn perform_action<T: MyTrait>(obj: T) {
    obj.action();
}

fn main() {
    let obj1 = Type1;
    let obj2 = Type2;

    perform_action(obj1);
    perform_action(obj2);
}

이제 perform_action 함수는 제네릭 함수로 구현되어 있으며, 런타임에 T 타입이 결정됩니다. 이를 통해 서로 다른 타입에 대해 동작을 수행할 수 있게 되었습니다.

결론

Rust에서 제네릭 함수를 사용하여 런타임에 다른 타입에 대해 다른 동작을 수행하는 것은 동적 디스패치를 이용하여 가능합니다. 트레이트 객체와 제네릭 함수를 활용하여 런타임 다형성을 구현할 수 있습니다. 이를 통해 안정적이고 안전한 Rust 코드를 작성하면서도 런타임에 다양한 동작을 수행할 수 있습니다.

참고문헌: