1-10 ジェネリクスの基本的な理解

ジェネリクスは、特定の型に依存せずに、使いまわせるコードを書くための仕組みです。
例えば、配列をソート( 順番を並べ替えること )する関数をジェネリクスを使用して定義すると、整数の配列だけでなく、文字列の配列や他の型の配列に対しても同じ関数を使用することができます。

ジェネリクスの定義方法

ジェネリクスは、型をStringやIntに、事前に決め打ちするのではなく、<T>のように定義します。

func 関数名<T>(value: T) -> T {
    return T型の値
}

ジェネリクスの型パラメータには任意の識別子を使うことができます。

一般的には タイプを意味する T がよく使われますが、それ以外の名前を使っても問題ありません。

例えば、<Element>、<GenericType>、<A>、<B>など、コンテキストに適した名前を選ぶことができます。
特定の規則や命名規約があるわけではなく、プログラマが読みやすい名前を使うことが重要です。

ジェネリクスの具体的な例

例えば、次のような関数があります。

// Int型の変数を引数にとり、Int型を返す関数です。
func fetchValue(value: Int) -> Int {
    return value
}

これはInt(整数)型の変数を引数にとり、Int型を返す関数です。
この関数はInt型に特化しており、他の型には使えません。

fetchValue(12) // 正常終了する
fetchValue("はろー") // エラーになる

ジェネリクスを使って、この関数を他の場面でも使い回せるように書くことができます。

func fetchValue<T>(value: T) -> T {
    return value
}

このように書くと、どんな型でも使える関数になります。 T は型パラメータで、関数が呼び出される際に実際の型に置き換わります。
例えば、整数型や文字列型、カスタムクラスなど、どんな型でも使えます。

// fetchValue関数は色々な型で使い回すことができる
let intValue = identity(value: 10) // Int(整数)型
let doubleValue = identity(value: 3.14) // double(浮動小数点数)型
let stringValue = identity(value: "Hello, World!") // String(文字列)型

print(intValue) // 10
print(doubleValue) // 3.14
print(stringValue) // "Hello, World!"

まとめ

  • ジェネリクスを使用すると特定の型に依存せずに、様々な型で使いまわせるコードを書くことができる
  • <T> などで宣言する

ドリル

func printArrayElements<T>(_ array: [T]) {
    for element in array {
        print(element)
    }
}