100 Exercises To Learn Rust - 4.5 trait bound 풀기

// TODO: 컴파일이 성공하도록 `min`에 필요한 트레이트 바운드를 추가하세요.
//  `std::cmp`의 문서를 참조하여 필요할 지도 모르는 트레이트에 대한 정보를 찾을 수 있습니다.

// Note: 컴파일러를 행복하게 하는 다른 트레이트 바운드가 있지만,
// 다른 _의미_가 동반됩니다. 우리는 이러한 다른 것들을 코스 후반에 ordered collections(e.g. BTreeMap)
// 을 이야기할 때 다룰 것입니다.

/// 두 값 중 최솟값을 반환합니다.
pub fn min<T>(left: T, right: T) -> T {
    if left <= right {
        left
    } else {
        right
    }
}

 

 

위 코드를 바로 실행하면 다음과 같은 오류가 발생한다.

 

error[E0369]: binary operation `<=` cannot be applied to type `T`                                                                                                      
  --> exercises\04_traits\05_trait_bounds\src\lib.rs:10:13
   |
10 |     if left <= right {
   |        ---- ^^ ----- T
   |        |
   |        T
   |
help: consider restricting type parameter `T` with trait `PartialOrd`
   |
9  | pub fn min<T: std::cmp::PartialOrd>(left: T, right: T) -> T {
   |             ++++++++++++++++++++++

 

 

제네릭 타입 T에 대해서 이항 연산 `<=`을 적용할 수 없다고 한다.

 

코드의 중복을 줄이기 위해 제네릭 타입을 사용할 수 있지만, 컴파일러는 해당 타입이 무슨 일을 하려는지 추론하지 못한다. 무슨 타입이 될지 모를 T에 어떤 트레이트가 구현되어 있는지 알 수 없다.

 

그래서 어떤 행동을 할 수 있는지, 트레이트 바운드를 통해 알려주는 것이다.

 

컴파일러가 std::cmp::PartialOrd 트레이트를 사용해보라고 알려주었다.

 

 

pub fn min<T>(left: T, right: T) -> T
where
    T: std::cmp::PartialOrd
{
    if left <= right {
        left
    } else {
        right
    }
}

 

 

PartialOrd 문서에 가보면 "Trait for types that form a partial order"라면서 partial order에 위키피디아 링크를 걸어놨는데, 위키피디아 설명을 보면 "부분 순서 집합은 비교 불가능한 두 원소를 가질 수 있다"라고 한다.

 

solution에서는 Ord를 사용했고, 두 개의 차이점을 설명해두었다.

 

Ord는 값이 비교가능하다는 것을 보장(guarantee)한다.

 

PartialOrd는 마찬가지로 값을 비교할 수는 있지만, 비교 자체가 불가능한 두 원소를 비교할 경우, 위 함수는 최솟값을 반환하는 것이 아니라 `right`에 해당하는 값을 반환하게 된다.