ジェネリック関数は、あらゆる型を扱うことができます。次は swapTwoInts(_:_:) 関数のジェネリックバージョン swapTwoValues(_:_:) です。

func swapTwoValues<T>(inout a: T, inout _ b: T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

swapTwoValues(_:_:) 関数の本体は、swapTwoInts(_:_:) 関数の本体とまったく同じです。しかし、swapTwoValues(_:_:) の 1 行目が、swapTwoInts(_:_:) とわずかに異なります。次は 1 行目を比較しています。

func swapTwoInts(inout a: Int, inout _ b: Int)
func swapTwoValues<T>(inout a: T, inout _ b: T)

ジェネリックバージョンの関数は、実際の(IntStringDouble のような)型名の代わりに、プレースホルダの型名(このケースでは T)を使用しています。プレースホルダの型名は、T が何であるかについては示していませんが、T が何であろうと、a と b がともに同じ型 T であることを示しています。T の代わりに使用される実際の型は、swapTwoValues(_:_:) 関数が呼び出されるたびに決まります。

他の違いは、ジェネリック関数の名前 (swapTwoValues(_:_:)) に続けて、プレースホルダの型名 (T) を山括弧内 (<T>) に置くことです。山括弧が、T は swapTwoValues(_:_:) 関数定義内のプレースホルダの型名であるということを Swift に伝えます。T がプレースホルダであるため、Swift は実際の型 T を探しません。

あらゆる型の 2 つの値を渡せることを除いて、ともに同じ型の値であれば、swapTwoInts と同じようにして swapTwoValues(_:_:) 関数を呼び出すことができます。swapTwoValues(_:_:) が呼び出されるたびに、関数に渡された値の型から T の型が推論されます。

次の 2 つの例では、T はそれぞれ Int と String と推論されます。

var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt は 107 で、anotherInt は 3

var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString は "world" で、anotherString は "hello"
NOTE
上で定義された swapTwoValues(_:_:) 関数は、Swift 標準ライブラリにあり、自動的に利用できるようになっているジェネリック関数 swap からアイデアを得ています。swapTwoValues(_:_:) 関数の振る舞いが必要な場合、実装することなく、Swift の既存の swap(_:_:) 関数を使用することができます。

Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.