質問: Swiftの基本文法はだいたい押さえたのですが、ジェネリクスだけはよくわかりません。 インスタンス生成側、メソッド呼び出し側で型を指定できるように、定義の時点では型を汎用にしておく、ということは理解できていますが、 定義の仕方や使い方、使うシーンが分かりません。 実際の実例を入れながら、初級者にも分かるようにご説明いただけないでしょうか?
回答: ジェネリクスはSwift以外の言語にもある考え方です(内容としては同じです)。ちょっと回り道になるかもしれませんが、ジェネリクスという考え方が出てくるまでの歴史的背景から簡単に紹介します(多分、その方が理解しやすいと思うので)。 古い言語(例えば、C)では、扱うデータ型が異なるだけで処理内容が同じというような場合、処理名(関数名やメソッド名)は全く違う名前で定義する必要がありました。例えば、足し算をするような処理でも、Int型のデータを扱う場合はIntAdd、Float型の場合はFloatAddと言った具合にです。 ``` int IntAdd(int a, int b) { int ans; ans = a + b; return ans; } float FloatAdd(float a, float b) { float ans; ans = a + b; return ans; } ``` これですと、使う側に**使う処理を強く意識させる**こととなり、開発効率があまり良くありません。 やがて、オブジェクト指向という概念が出てきました。オブジェクト指向では関数オーバーロードという考え方があり、扱うデータ(戻り値や引数)の型が異なれば処理名は同じでも構わないという書き方ができるようになりました。 ``` int Add(int a, int b) { int ans; ans = a + b; return ans; } float Add(float a, float b) { float ans; ans = a + b; return ans; } ``` これにより、使う側は「足し算をする時はAddを使えばいい」ということだけを意識すればいいようになりました。 使う側とすれば便利にはなりましたが、作る側は(必要な)データ型の数の分だけ用意した処理を開発/保守していかなければいけません。例えば、同様な修正が全てに入るような場合、該当するすべての処理に手を入れていかなければなりません(当然ですが)。そこで、定義時はあまり型を強く意識しないようにし、利用時に該当するデータ型に適宜展開して処理できるようにする書き方としてジェネリクスができました。つまり、保守の効率化を図ったのがジェネリクスということになります(私はそう捉えています)。 長くなりましたが、大雑把に言えばこんな感じです。後は以下のページを見てみてはいかがでしょうか。 Swift言語を学ぶ - ジェネリクス Swiftのジェネリクスについてのメモ Codable Tech BLog - Swiftジェネリックス