関数

同じことが関数でも言えます。つまり、<T>のように指定された型Tは ジェネリックになります。

ジェネリックな関数を使う時は、返り値がジェネリック型であり、それをコンパイラ が推論できない場合、明示的な型パラメータが必要になります。

このように、明示的な型宣言を使って関数を呼び出すことができます。 fun::<A, B, ...>().

struct A;          // 具象型`A`
struct S(A);       // 具象型`S`
struct SGen<T>(T); // ジェネリック型`SGen`

// 以下の関数はすべて変数の所有権をもらい、すぐにスコープを抜けるため、
// 変数を開放します。

// `S`型の引数`_s`を取る関数`reg_fn`を定義する。
// ジェネリックな関数ではないので、`<T>`を使わない。
fn reg_fn(_s: S) {}

// `SGen<A>`型の引数`_s`を取る関数`gen_spec_t`を定義する。
// `A`はジェネリックな型パラメータとして定義されていないため、
// これはジェネリックではない。
fn gen_spec_t(_s: SGen<A>) {}

// `SGen<i32>`型の引数`_s`を取る関数`gen_spec_i32`を定義する。
// `i32`はジェネリックではないので、この関数もジェネリックでない。
fn gen_spec_i32(_s: SGen<i32>) {}

// `SGen<T>`型の引数`_s`をとる関数`generic`を定義する。
// `<T>`があるため、`SGen<T>`はジェネリックであり、この関数は`T`に対してジェネリックです。
fn generic<T>(_s: SGen<T>) {}

fn main() {
    // 非ジェネリックな関数を使う
    reg_fn(S(A));          // 具象型
    gen_spec_t(SGen(A));   // 型パラメータ`A`を暗示的に渡す。
    gen_spec_i32(SGen(6)); // 型パラメータ`i32`を暗示的に渡す。

    // 明示的に`char`を`generic()`の型パラメータとして渡す。
    generic::<char>(SGen('a'));

    // 暗示的に`char`が`generic()`の型パラメータとなる。
    generic(SGen('c'));
}

こちらも参照: