问题
对于其容器类型泛型的 trait
有类型规范要求 - trait
的使用者*必须*指定其所有泛型类型。
在下面的示例中,Contains
trait
允许使用泛型类型 A
和 B
。然后为 Container
类型实现该 trait,为 A
和 B
指定 i32
,以便它可以与 fn difference()
一起使用。
因为 Contains
是泛型的,所以我们被迫为 fn difference()
显式声明*所有*泛型类型。在实践中,我们希望有一种方法来表达 A
和 B
是由*输入* C
决定的。正如您将在下一节中看到的那样,关联类型提供了这种能力。
struct Container(i32, i32); // A trait which checks if 2 items are stored inside of container. // Also retrieves first or last value. trait Contains<A, B> { fn contains(&self, _: &A, _: &B) -> bool; // Explicitly requires `A` and `B`. fn first(&self) -> i32; // Doesn't explicitly require `A` or `B`. fn last(&self) -> i32; // Doesn't explicitly require `A` or `B`. } impl Contains<i32, i32> for Container { // True if the numbers stored are equal. fn contains(&self, number_1: &i32, number_2: &i32) -> bool { (&self.0 == number_1) && (&self.1 == number_2) } // Grab the first number. fn first(&self) -> i32 { self.0 } // Grab the last number. fn last(&self) -> i32 { self.1 } } // `C` contains `A` and `B`. In light of that, having to express `A` and // `B` again is a nuisance. 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)); }