12.7.1 The Problem
그 자신의 포괄 타입에 대해 제네릭 되는 trait
은 타입에 대한 선언이 요구된다. - trait
사용자는 반드시 그 자신의 제네릭 타입을 명시해야 한다.
아래의 예제에서, Contains
trait
이 제네릭 타입 A
와 B
의 사용을 허용한다. trait은 Container
타입에 구현되고, i32
를 A
와 B
에 명시하여 fn difference()
에서 사용될 수 있다.
Containes
가 제네릭이라, 우리는 fn difference()
을 위한 제네릭 타입 모두의 명시적 상태를 강제해야 한다. 실제로, 우리가 원하는 표현 방식은 A
와 B
가 입력 값 C
에 의해 결정되는 것이다. 당신이 다음 섹션에서 볼 수 있는 연관된 타입들은 정확히 이 기능을 제공한다.
struct Container(i32, i32); // 컨테이너 내부에 2개의 아이템이 저장되어 있는지 확인하는 trait. // 또한 첫 번째 또는 마지막 값을 반환한다. trait Contains<A, B> { fn contains(&self, &A, &B) -> bool; // `A`와 `B`의 명시적 요구. fn first(&self) -> i32; // 명시적이지 않은 `A`나 `B`의 요구 fn last(&self) -> i32; // 명시적이지 않은 `A`나 `B`의 요구 } impl Contains<i32, i32> for Container { // 저장된 숫자가 같으면 True. fn contains(&self, number_1: &i32, number_2: &i32) -> bool { (&self.0 == number_1) && (&self.1 == number_2) } // 첫 번째 숫자를 가져온다. fn first(&self) -> i32 { self.0 } // 마지막 번호를 가져온다. fn last(&self) -> i32 { self.1 } } // `C`는 `A`와 `B`를 포함한다. 이 점을 고려하면 // `A`와 `B`를 다시 표현하는 것은 성가시다. fn difference<A, B, C>(container: &C) -> i32 where C: Contains<A, B> { container.last() - container.first() } fn main() { let number_1 = 3; let number_2 = 10; let container = Container(number_1, number_2); println!("Does container contain {} and {}: {}", &number_1, &number_2, container.contains(&number_1, &number_2)); println!("First number: {}", container.first()); println!("Last number: {}", container.last()); println!("The difference is: {}", difference(&container)); }