【Swift】ジェネリクスの意味と使い方!Comparableプロトコルとは?

この記事からわかること
- Swiftのジェネリクスとは?
- 意味や使い方、メリット
- 関数や構造体への組み込み方
- Comparableプロトコルとは?
index
[open]
\ アプリをリリースしました /
ジェネリクスとは?
ジェネリクスとはSwift言語の仕様の1つで、特定のデータの型に依存しない関数などを定義することができます。Swift内部でもジェネリクスは使用されており、タプルや配列などが異なるデータ型を保持できるのもこのジェネリクスを使用しているからのようです。
ジェネリクスのような仕様は他言語でも実装されている仕様でジェネリックプログラミングとも呼ばれています。generic(:ジェネリック)は日本語で「一般的な」を意味する英単語です。
ジェネリクスの構文と使い方
ジェネリクスは型を定義する様に使用したり、関数名の後に<任意の型名>
を使って使用します。型名は任意の名称を付けることができますが、慣習的にT
が使われることが多いようです。また任意の際の命名規則はキャメルケース(CamelCase)を用いることが推奨されています。
例えば下記のような引数のデータ型を出力してnil
を返す関数を定義するとします。関数名の後にジェネリクスを表す<T>
を、引数には2つとも様々なデータ型でも許容できるように同様にT
を指定します。今回は返り値にnil
を許容できるようにオプショナル型にします。型の制限を設けないジェネリクスですがオプショナル型は許容していないので明示的に?
を使ってオプショナル型を許容します。
上記の実行結果
judgeType
関数は1つしか定義していませんが、異なるデータ型を引数で受け取ってもエラーになることなく実行することができます。しかし今回のように引数2つともにジェネリクスT
を指定した場合、両者のデータ型は同じでなければなりません。
またこのようにジェネリクスを用いた関数のことをジェネリクス関数と呼びます。
ジェネリクスのポイント
- データ型の制限をなくす
- ジェネリクスは「T」もしくはキャメルケースで命名する(慣習的に)
- nil(オプショナル型)は許容できない
- ジェネリクスを指定した複数の引数は同じデータ型でないとエラーになる
- 関数内で比較をしたい場合はComparableプロトコルを指定
Comparableプロトコルでジェネリクス関数に比較式を許容する
ジェネリクスを引数に用いている場合に関数の中で比較( = や > など)をしてしまうとエラーになってしまいます。
比較を用いた場合のパースエラー
これを防ぐにはT
の後にComparableプロトコル
を指定します。
エラーになってしまう理由はどんなデータ型でも許容できる代わりに、比較できないデータ型を渡される可能性もあるためです。
Comparable
プロトコルは値の比較が可能なデータ型であることをルールとしているプロトコルです。
Comparableプロトコルの定義
受ける変数の型によってメソッド内の型を変更する
ジェネリクスを使用して以下のようにメソッド自体には引数などで受け取らず、受け取る変数の型に応じてメソッド内の処理を切り替えることも可能です。
構造体にジェネリクスを指定する
構造体にジェネリクスを指定する場合も関数と同様に<T>
のように定義します。
またプロパティ(変数)にもBox<T>
部分で指定した型名でジェネリクスとして指定することができるようになります。
プロトコルへのジェネリックプログラミング
Swiftのプロトコルに対してジェネリックプログラミングな実装をするために用意されているassociatedtype
キーワードが用意されています。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。