[Rust/러스트] 제네릭(Generic) 정리

2022. 2. 23. 16:09Programming Language/Rust

반응형

■ 제네릭

제네릭은 컨셉의 복제를 효율적으로 다루기 위한 도구로서, 구체화된 타입이나 다른 속성들에 대하여 추상화된 대리인의 역할을 수행합니다. 제네릭은 함수, 구조체, 열거형, 메소드를 정의할 때 사용할 수 있습니다.


◆ 제네릭 함수 활용

제네릭을 함수에 활용함으로써 다양한 타입의 파라미터를 받아 작업을 수행할 수 있습니다.

 

예시) T는 [i32], [f32], [&str] 타입의 파라미터를 받고 있으며, 파라미터를 그대로 반환하는 show 함수를 통해 함수에서의 제네릭 활용법을 확인할 수 있습니다.

fn show<T>(data : T) -> T {
    data
}

fn main(){
    println!("i32 data : {}", show(29));
    println!("f32 data : {}", show(0.2));
    println!("&str data : {}", show("Hyunmin"));
}

▶ 출력 결과

i32 data : 29
f32 data : 0.2
&str data : Hyunmin

◆ 제네릭 구조체 활용

제네릭을 구조체에 활용함으로써 필드의 타입을 유동적으로 정의하고, 생산성을 높일 수 있습니다.

 

예시) Location 구조체의 x 필드는 T 타입, y 필드는 U 타입으로 정의되었기 때문에 서로 같거나 다른 다양한 타입의 필드를 갖는 Location 인스턴스를 생성할 수 있습니다.

#[derive(Debug)]
struct Location<T,U>{
    x : T,
    y : U
}

fn main(){
    // x : i32, y : i32
    let a_loc = Location {x : 130, y : 100};
    // x : i32, y : f32
    let b_loc = Location {x : 135, y : 35.7};

    println!("a location : {:?}", a_loc);
    println!("b location : {:?}", b_loc);
}

▶ 출력 결과

a location : Location { x: 130, y: 100 }
b location : Location { x: 135, y: 35.7 }

◆ 제네릭 열거형 활용

구조체에서의 활용과 유사하게 열거형 항목의 타입을 유동적으로 정의함으로써 생산성을 높일 수 있습니다.

 

예시) Color 열거형을 생성하는데 Red 항목은 [&str] 와 [tuple] 타입의 데이터를 갖을 수 있도록 생성할 수 있습니다.

#[derive(Debug)]
enum Color<T>{
    Red(T)
}

fn main(){
    let rgb_str_red = Color::Red("255,0,0");
    let rgb_tuple_red = Color::Red((255, 0, 0));
    println!("rgb str red : {:?}", rgb_str_red);
    println!("rgb tuple red : {:?}", rgb_tuple_red);
}

▶ 출력 결과

rgb str red : Red("255,0,0")
rgb tuple red : Red((255, 0, 0))

◆ 제네릭 메소드 활용

제네릭 타입으로 구조체 또는 열거형의 메소드를 구현함으로써 함수의 활용과 같이 다양한 타입을 갖는 파라미터를 받아 작업을 수행할 수 있습니다.

 

예시) impl 문법은 구조체와 동일하게 제네릭을 설정합니다. Location 구조체의 show 메소드는 파라미터로 Location 구조체를 받을 수 있는데, 타입은 show를 호출한 인스턴스와 다른 타입인 V, W 로 설정할 수 있습니다.

use std::fmt::Debug;

#[derive(Debug)]
struct Location<T,U>{
    x : T,
    y : U
}

impl<T,U> Location<T,U>
    where T : Debug,
          U : Debug
{
    fn show<V,W>(&self, other : Location<V,W>)-> &T
        where V : Debug,
              W : Debug
    {
        println!("Self : {:?}", self);
        println!("Other : {:?}", other);
        &self.x
    }
}

fn main(){
    // T : i32, U : i32
    let a_loc = Location {x : 130, y : 100};
    // V : &str, W : f32
    let b_loc = Location {x : "135", y : 35.7};

    a_loc.show(b_loc);
}

▶ 출력 결과

Self : Location { x: 130, y: 100 }
Other : Location { x: "135", y: 35.7 }
반응형