実行環境

  • Swift4
  • Xcode9.2

ジェネリクスとは

プロパティやメソッドで使用される型が実際に使う段階で決定される機能のこと。
これによりIntやStringなどの型に左右されずに、柔軟に動作する関数やクラスを定義することができる。

ジェネリック関数

定義

func 関数名<T>(引数名: ) -> 戻り値の型 {
  // 処理
}
  • 関数名の後に型パラメータ<T>を指定する
  • ジェネリクスの型は<T>でなくても構わないが、一般的には<T>が使われる

基本的な使い方

通常の関数の場合

// Int型の引数を受け取り、そのまま引数の値をタプルで返す関数
func test(param1: Int, param2: Int) -> (Int, Int) {
    return (param1, param2)
}
let result = test(param1: 1, param2:2)
print(result.0) // 結果: 1
print(result.1) // 結果: 2

上記だと、Int型以外の引数を渡すとコンパイルエラーとなる

ex.Double型の値を引数に指定
let result = test(param1: 1.0, param2:2.0) // コンパイルエラー

なので、Double型に対応するには、Double型の引数を受け取る関数を作る必要がある。

// Double型の引数を受け取り、そのまま引数の値をタプルで返す関数
func test(param1: Double, param2: Double) -> (Double, Double) {
    return (param1, param2)
}
let result = test(param1: 1.0, param2: 2.0)
print(result.0) // 結果: 1.0
print(result.1) // 結果: 2.0

同様に、String型に対応するにはString型の、Boolean型に対応するにはBoolean型の関数を作る必要があり、型ごとに作業が発生し、手間がかかる。

// String型の引数を受け取り、そのまま引数の値をタプルで返す関数
func test(param1: String, param2: String) -> (String, String) {
  return (param1, param2)
}

// Boolean型の引数を受け取り、そのまま引数の値をタプルで返す関数
func test(param1: Bool, param2: Bool) -> (Bool, Bool) {
  return (param1, param2)
}

ジェネリック関数の場合

func testGenerics<T> (param1: T, param2: T) -> (T, T) {
    return (param1, param2)
}

ジェネリック関数は引数や返り値から型を推論するため、型ごとに同じような関数を作る必要がなく、一度の定義でどの型にも対応することができる。

// Int型
let resultInt = testGenerics(param1: 1, param2: 2)

// Double型
let resultDouble = testGenerics(param1: 1.0, param2: 2.0)

// String型
let resultString = testGenerics(param1: "1", param2: "2")

// Boolean型
let resultBool = testGenerics(param1: true, param2: false)

ジェネリッククラス

定義

class クラス名<T> {
  // 処理
}
  • クラス名の後に型パラメータ<T>を指定する
  • ジェネリクスの型は<T>でなくても構わないが、一般的には<T>が使われる

基本的な使い方

class Test<T> {
    var data: T

    init(data: T) {
        self.data = data
    }
}

// Int型
let resultInt = Test(data: 10)
// 型の確認
print(type(of: resultInt.data)) // 結果: Int
// 値の確認
print(resultInt.data) // 結果: 10

// Double型
let resultDouble = Test(data: 1.0)
// 型の確認
print(type(of: resultDouble.data)) // 結果: Double
// 値の確認
print(resultDouble.data) // 結果: 1.0

// String型
let resultString = Test(data: "Hello")
// 型の確認
print(type(of: resultString.data)) // 結果: String
// 値の確認
print(resultString.data) // 結果: Hello

// Boolean型
let resultBoolean = Test(data: true)
// 型の確認
print(type(of: resultBoolean.data)) // 結果: Boolean
// 値の確認
print(resultBoolean.data) // 結果: true
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.