애플리케이션을 개발하는 동안에는 항상 불확실성이 존재하며, 특히 함수가 특정 타입의 인수를 허용하는 경우 오류가 발생할 수 있습니다. 불확실성으로 인한 오류를 줄이기 위해 제네릭을 사용할 수 있습니다. 제네릭은 다양한 형식으로 작업하기 위한 클래스, 함수 및 데이터 구조를 생성하는 기능을 제공합니다.
제네릭을 사용하면 복잡한 코드를 작성하거나 각 형식에 대해 별도의 구현을 작성하지 않고도 여러 형식에서 작동할 수 있는 알고리즘과 데이터 구조를 생성하고 정의할 수 있습니다. 제네릭은 타입 안전성과 성능을 유지하면서 코드 재사용성과 효율성을 향상시킵니다.
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 특성을 구현합니다.
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)과 함께 사용하기에 좋습니다. 제네릭 유형을 사용하면 트레잇을 구현하는 모든 타입에서 작동하는 트레잇 객체를 생성하여 메서드를 보다 유연하게 만들 수 있습니다.