LoginSignup
2
1

More than 5 years have passed since last update.

ジェネリクスでオーバーロードいらず!?

Posted at

ジェネリクスを使うと型を特定せずに同じメソッドやクラスで別のプログラムができます。

まずはジェネリクスを利用した関数から説明していきます。

import Foundation

func test<T>(n1:T)->T{
    return n1
}

var num1:Int = 100
print(test(num1)) //100と表示

testというn1というパラメーターを持つ関数です。<T>というものがくっついています。
<T>のTはタイプパラメーターといいますが、Tという文字である必要はありません。一般的な書き方がそうなだけです。
test関数内では特に型を定めていません。num1でInt型に設定し、100という数字を代入しています。

型を決めてしまうと同じ処理をさせるには型の制約を受けることになります。
例えば以下のような場合です。


import Foundation

class NoGenerics {
    func test (param: String) -> String{
        return param
    }

    func test (param: Int) -> Int{
        return param
    }

    func test (param: Double) -> Double{
        return param
    }
}

var age = NoGenerics()

print(age.test("HI"))    //HIと表示
print(age.test(100))     //100と表示
print(age.test(9.999))   //9.999と表示

違う型のtestという同じ名前の関数を持つクラスNoGenericsではメソッドで呼ばれるときに与えたパラメーターの型を推測して値を返しています。いわゆるオーバーロードです。

ジェネリクスでfunc test<T>とすることで呼ばれるときにパラメーターの型を指定すれば1回書けば済んでしまいます。

次にクラスでジェネリクスを利用した例を書きます。

import Foundation

class NazoPerson<T,U> {
    let name: T
    var age: U
    init(name: T, age: U){
        self.name = name
        self.age = age
    }
}

var i_am_taro = NazoPerson<String, Int>(name: "曙太郎", age: 100)
var i_am_shiro = NazoPerson<Int, String>(name: 46, age: "四十六")

print("名前:\(i_am_taro.name), 年齢\(i_am_taro.age)歳") //名前:曙太郎, 年齢100歳
print("名前:\(i_am_shiro.name), 年齢\(i_am_shiro.age)歳") //名前:46, 年齢四十六歳

名前も年齢も型を決めないNazoPersonクラスでnameにT、ageにUというタイプパラメーターをつけました。i_am_...で型を決めています。

ジェネリクスを応用すれば色々なことができますね\(^o^)/

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1