ジェネリクス
_ジェネリクス_とは、型や機能をより広範なケースへ一般化するというトピックです。これは、多くの方法でコードの重複を減らすうえで非常に有用ですが、かなり複雑な構文を必要とすることがあります。つまり、ジェネリックであるためには、ジェネリック型が実際にどの型に対して有効と見なされるのかを細心の注意を払って指定する必要があります。ジェネリクスの最も単純で一般的な用途は、型パラメーターです。
型パラメーターは、山括弧とアッパーキャメルケースを使用してジェネリックとして指定されます: <Aaa, Bbb, ...>。"ジェネリック型パラメーター"は、通常 <T> として表されます。Rust では、"ジェネリック" は 1 つ以上のジェネリック型パラメーター <T> を受け取るものすべてを表す言葉でもあります。ジェネリック型パラメーターとして指定された型はすべてジェネリックであり、それ以外はすべて具象(非ジェネリック)です。
たとえば、任意の型の引数 T を受け取る foo という名前の_ジェネリック関数_を定義します。
fn foo<T>(arg: T) { ... }
T は <T> を使ってジェネリック型パラメーターとして指定されているため、ここで (arg: T) として使われるとき、ジェネリックと見なされます。これは、たとえ T が以前に struct として定義されていたとしても同様です。
この例は、構文の一部が実際に使われている様子を示しています。
// 具象型 `A`。 struct A; // 型 `Single` を定義する際、`A` の最初の使用の前には `<A>` がありません。 // したがって、`Single` は具象型であり、`A` は上で定義されたものです。 struct Single(A); // ^ ここが `Single` における型 `A` の最初の使用です。 // ここでは、`T` の最初の使用の前に `<T>` があるため、`SingleGen` はジェネリック型です。 // 型パラメーター `T` はジェネリックなので、最上部で定義された具象型 `A` を含め、 // 何にでもなり得ます。 struct SingleGen<T>(T); fn main() { // `Single` は具象であり、明示的に `A` を受け取ります。 let _s = Single(A); // 型 `SingleGen<char>` の変数 `_char` を作成し、 // 値 `SingleGen('a')` を与えます。 // ここでは、`SingleGen` の型パラメーターが明示的に指定されています。 let _char: SingleGen<char> = SingleGen('a'); // `SingleGen` では、型パラメーターを暗黙的に指定することもできます: let _t = SingleGen(A); // 最上部で定義された `A` を使います。 let _i32 = SingleGen(6); // `i32` を使います。 let _char = SingleGen('a'); // `char` を使います。 }