関数
同じルールのセットを関数にも適用できます。型 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<T>` の引数 `_s` を取る関数 `gen_spec_t` を定義します。
// 型パラメータ `A` が明示的に与えられていますが、`A` が `gen_spec_t` のジェネリック型パラメータとして指定されていないため、これはジェネリックではありません。
fn gen_spec_t(_s: SGen<A>) {}
// 型 `SGen<i32>` の引数 `_s` を取る関数 `gen_spec_i32` を定義します。
// 型パラメータ `i32` が明示的に与えられており、これは特定の型です。
// `i32` はジェネリック型ではないため、この関数もジェネリックではありません。
fn gen_spec_i32(_s: SGen<i32>) {}
// 型 `SGen<T>` の引数 `_s` を取る関数 `generic` を定義します。
// `SGen<T>` の前に `<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`。
// `generic()` に明示的に型パラメータ `char` を指定する。
generic::<char>(SGen('a'));
// `generic()` に暗黙的に型パラメータ `char` を指定する。
generic(SGen('c'));
}