Rust by Example - страница 37
>
>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The same set of rules can be applied to functions: a type T becomes generic when preceded by
Using generic functions sometimes requires explicitly specifying type parameters. This may be the case if the function is called where the return type is generic, or if the compiler doesn't have enough information to infer the necessary type parameters.
A function call with explicitly specified type parameters looks like: fun::().
>struct A; // Concrete type `A`.
>struct S(A); // Concrete type `S`.
>struct SGen
>// The following functions all take ownership of the variable passed into
>// them and immediately go out of scope, freeing the variable.
>// Define a function `reg_fn` that takes an argument `_s` of type `S`.
>// This has no `
>fn reg_fn(_s: S) {}
>// Define a function `gen_spec_t` that takes an argument `_s` of type `SGen
>// It has been explicitly given the type parameter `A`, but because `A` has not
>// been specified as a generic type parameter for `gen_spec_t`, it is not generic.
>fn gen_spec_t(_s: SGen) {}
>// Define a function `gen_spec_i32` that takes an argument `_s` of type `SGen
>// It has been explicitly given the type parameter `i32`, which is a specific type.
>// Because `i32` is not a generic type, this function is also not generic.
>fn gen_spec_i32(_s: SGen
>// Define a function `generic` that takes an argument `_s` of type `SGen
>// Because `SGen
>fn generic
>fn main() {
>// Using the non-generic functions
>reg_fn(S(A)); // Concrete type.
>gen_spec_t(SGen(A)); // Implicitly specified type parameter `A`.
>gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`.
>// Explicitly specified type parameter `char` to `generic()`.
>generic::
>// Implicitly specified type parameter `char` to `generic()`.
>generic(SGen('c'));
>}
>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Similar to functions, implementations require care to remain generic.
>#![allow(unused)]
>fn main() {
>struct S; // Concrete type `S`
>struct GenericVal
>// impl of GenericVal where we explicitly specify type parameters:
>impl GenericVal
>impl GenericVal
{} // Specify `S` as defined above
>// `
>impl
>}
>struct Val {
>val: f64,
>}
>struct GenVal
>gen_val: T,
>}
>// impl of Val
>impl Val {
>fn value(&self) -> &f64 {
>&self.val
>}
>}
>// impl of GenVal for a generic type `T`
>impl
>fn value(&self) -> &T {
>&self.gen_val
>}
>}
>fn main() {
>let x = Val { val: 3.0 };
>let y = GenVal { gen_val: 3i32 };
>println!("{}, {}", x.value(), y.value());
>}
>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX