12.4 Bounds

제네릭으로 동작할 때, 타입 매개변수는 종종 바인드 된 trait을 사용하여 타입 구현의 기능성을 규정해야 한다. 예시로서 다음의 예제는 Display trait을 사용하여 출력하고자 하는데 그래서 TDisplay에 바인드 되어야 한다; 이에 따라, T반드시 Display를 구현해야 한다. When working with generics, the type parameters often must use traits as bounds to stipulate what functionality a type implements. For example, the following example uses the trait Display to print and so it requires T to be bound by Display; that is, T must implement `Display

// 반드시 `Display`를 구현해야 하는 제네릭 타입 `T`를 
// 취하는 함수 `printer`를 정의한다.
fn printer<T: Display>(t: T) {
    println!("{}", t);
}

제네릭을 타입에 바인드 시키는 제약은 바인드 되는 대상에 따른다. 이는: Bounding restricts the generic to types that conform to the bounds. That is:

struct S<T: Display>(T);

// 에러! `Vec<T>`는 `Display`를 구현하지 않았다. 
// 이 특수 문장은 실패할 것이다.
let s = S(vec![1]);

바인딩의 다른 효과는 제네릭 인스턴스가 바인드에 지정된 trait의 [메소드]에 접근이 허용된다. 예를 들어: Another effect of bounding is that generic instances are allowed to access the methods of traits specified in the bounds. For example:

// 출력 마커를 구현한 trait: `{:?}`.
use std::fmt::Debug;

trait HasArea {
    fn area(&self) -> f64;
}

impl HasArea for Rectangle {
    fn area(&self) -> f64 { self.length * self.height }
}

#[derive(Debug)]
struct Rectangle { length: f64, height: f64 }
#[allow(dead_code)]
struct Triangle  { length: f64, height: f64 }

// 제네릭 `T`는 `Debug`를 구현해야 한다. 타입에 관계 없이 
// 이것은 제대로 작동한다.
fn print_debug<T: Debug>(t: &T) {
    println!("{:?}", t);
}

// `T`는 `HasArea`를 구현해야 한다. 바인드 된 대상과 결합되는 모든 함수가
// `HasArea`의 함수 `area`에 접근할 수 있다.
fn area<T: HasArea>(t: &T) -> f64 { t.area() }

fn main() {
    let rectangle = Rectangle { length: 3.0, height: 4.0 };
    let _triangle = Triangle  { length: 3.0, height: 4.0 };

    print_debug(&rectangle);
    println!("Area: {}", area(&rectangle));

    //print_debug(&_triangle);
    //println!("Area: {}", area(&_triangle));
    // ^ TODO: 이들의 주석을 제거해보세요.
    // | 에러! : `Debug` 혹은 `HasArea`를 구현하지 않음.
}

추가로 주의할 점은, where 항목도 더 표현하고자 하는 경우에 바인드 되는 대상으로 적용하는데 사용될 수 있다. As an additional note, where clauses can also be used to apply bounds in some cases to be more expressive.

See also:

std::fmt, structs, and traits

results matching ""

    No results matching ""