#ジェネリクスを使うと型を特定せずに同じメソッドやクラスで別のプログラムができます。#
まずはジェネリクスを利用した関数から説明していきます。
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^)/