애플리케이션을 개발하는 동안에는 항상 불확실성이 존재하며, 특히 함수가 특정 타입의 인수를 허용하는 경우 오류가 발생할 수 있습니다. 불확실성으로 인한 오류를 줄이기 위해 제네릭을 사용할 수 있습니다. 제네릭은 다양한 형식으로 작업하기 위한 클래스, 함수 및 데이터 구조를 생성하는 기능을 제공합니다.

제네릭을 사용하면 복잡한 코드를 작성하거나 각 형식에 대해 별도의 구현을 작성하지 않고도 여러 형식에서 작동할 수 있는 알고리즘과 데이터 구조를 생성하고 정의할 수 있습니다. 제네릭은 타입 안전성과 성능을 유지하면서 코드 재사용성과 효율성을 향상시킵니다.

Rust에서 제네릭 타입 사용하기

Rust의 제네릭 타입은 다른 Rust 데이터 타입과 상호 운용할 수 있습니다. 꺾쇠 괄호(‘&’) 뒤에 두 개 이상의 매개 변수를 사용하여 일반 유형을 정의합니다.

다음은 두 개의 제네릭 타입 매개변수를 사용하는 제네릭 구조체 정의입니다:

struct Point<T, U> {
    // T and U are generic type parameters that the x and y fields will 
    // assume on instantiation
    x: T,
    y: U,
}

Point 구조체에서 T, U 은 제네릭 타입 파라미터입니다.

인스턴스화 시 일반 유형 파라미터를 모든 데이터 유형으로 대체할 수 있습니다:

fn main() {
    let my_point = Point { x: String::from("hello"), y: String::from("world") };

    println!(
       "The x value of my_point is {} and the y value is {}.",
       my_point.x,
       my_point.y
   );
}

my_point 변수는 문자열 유형으로 초기화된 Point 구조체의 인스턴스입니다. Rust 컴파일러는 인스턴스화 값을 기반으로 T U 의 구체적인 유형을 추론합니다.

제네릭 타입에 대한 특성 바운드

Rust 제네릭 타입은 특성 바운드를 사용하여 타입 안전을 보장할 수 있습니다. 특성은 유형이 해당 특성에 대해 정의된 특정 동작을 구현하기 위해 구현할 수 있는 메서드의 모음입니다.

특성 바운드는 제네릭 유형이 하나 이상의 특성을 구현해야 함을 지정합니다.

다음은 비교되는 유형이 특성을 구현하도록 하는 특성 바인딩이 있는 두 값 중 더 큰 값을 반환하는 일반 함수의 예입니다.

// Maximum is a trait that defines a method for evaluating the maximum of two
// types
trait Maximum {
    fn max(self, other: Self) -> Self;
}

// Implements the `Maximum` trait for all types that implement the
// `PartialOrd` trait.
impl<T: PartialOrd> Maximum for T {
    fn max(self, other: Self) -> Self {
        // return `self` if it is greater than `other`; otherwise, return
       // `other.`
        if self > other {
            self
        } else {
            other
        }
    }
}

fn main() {
    let a = 5;
    let b = 10;
    let largest = Maximum::max(a, b);
    println!("The largest value is {}", largest);
}

최대 특성에는 동일한 유형의 두 값 중 더 큰 값을 반환하는 최대 메서드가 있습니다. PartialOrd 특성을 구현하는 모든 유형은 Maximum 특성을 구현합니다.

이 글도 확인해 보세요:  HTTP와 HTTPS: 차이점은 무엇인가요?

max 메서드는 Self 유형의 두 값( Maximum 특성을 구현하는 유형을 참조)을 가져와서 값을 비교합니다.

기본 함수는 최대 메서드를 사용하여 두 변수를 비교하고 가장 큰 값을 인쇄합니다.

일반 유형에 대한 제약 조건

제약 조건은 특성 바운드와 유사하지만 유형 매개변수로 사용 중인 유형에 대한 추가 요구 사항을 지정할 수 있습니다.

문자열 변환을 위해 유형을 허용하는 일반 함수를 만들려는 경우 제약 조건을 사용하여 유형 매개 변수가 특성을 구현하도록 할 수 있습니다.

// ToString is a trait with a string conversion method
trait ToString {
    fn to_string(&self) -> String;
}

// to_string is a generic function that takes a value of any type that
// implements the ToString trait
fn to_string<T: ToString>(value: T) -> String {
    value.to_string()
}

to_string 값 매개 변수는 ToString 특성을 구현해야 T 유형의 값을 to_string 메서드를 사용하여 문자열로 변환할 수 있습니다.

제네릭 유형은 트레잇(Trait)과 함께 사용하기에 좋습니다

Rust 제네릭 형식은 강력하지만 개선해야 할 부분이 있습니다. 중요한 초점 영역은 제네릭 코드의 성능을 개선하는 것입니다. 현재 Rust의 타입 시스템은 제네릭 코드에 오버헤드를 부과하여 성능을 저하시킬 수 있습니다.

제네릭 타입은 트레잇(Trait)과 함께 사용하기에 좋습니다. 제네릭 유형을 사용하면 트레잇을 구현하는 모든 타입에서 작동하는 트레잇 객체를 생성하여 메서드를 보다 유연하게 만들 수 있습니다.

By 최은지

윈도우(Windows)와 웹 서비스에 대한 전문 지식을 갖춘 노련한 UX 디자이너인 최은지님은 효율적이고 매력적인 디지털 경험을 개발하는 데 탁월한 능력을 발휘합니다. 사용자의 입장에서 생각하며 누구나 쉽게 접근하고 즐길 수 있는 콘텐츠를 개발하는 데 주력하고 있습니다. 사용자 경험을 향상시키기 위해 연구를 거듭하는 은지님은 All Things N 팀의 핵심 구성원으로 활약하고 있습니다.