Tupleとは
Tupleとは複数の値の集合で、配列やディクショナリーに近いものです。
しかしメソッドを持っていなかったり様々型の値を混在させられたりと独特の性質を多く持っています。
この記事ではTupleの様々な仕様について書いていこうと思います。
よくある使い方
要素へは.0, .1, .2という形でアクセスします。
Arrayと違って様々な型を混在させる事ができます。
let tuple = (1, 2, "3")
print(tuple.0) // 1
print(tuple.1) // 2
print(tuple.2) // 3
ラベル名付きのTuple
let tuple = (int: 1, str: "2")
print(tuple.int) // 1
print(tuple.str) // 2
補完には出てきませんが通常のTupleと同じアクセス方法も使えます。
let tuple = (int: 1, str: "2")
print(tuple.0) // 1
ラベル付きとラベル無しの混在
ラベル付きとラベル無しの要素を混在させる事ができます。
let tuple2 = (int1: 1, 2)
print(tuple2.int1)
print(tuple2.1)
ラベル付きとラベル無しの型
dynamicTypeで型を調べるとどちらも同じ型のように見えます。
let tuple1: (Int, Int) = (1, 2)
let tuple2: (int1: Int, Int) = (int1: 1, int2: 2)
print(tuple1.dynamicType) // (Int, Int)
print(tuple2.dynamicType) // (Int, Int)
Mirrorでプロパティー一覧を調べたところ、どちらも.0と.1がありました。
ラベルはプロパティー一覧で取得できなかったのが意外でした。
let tuple1: (Int, Int) = (1, 2)
let tuple2: (int1: Int, int2: Int) = (int1: 1, int2: 2)
print(Mirror(reflecting: tuple1).children.map { $0.label }) // [Optional(".0"), Optional(".1")]
print(Mirror(reflecting: tuple2).children.map { $0.label }) // [Optional(".0"), Optional(".1")]
ラベル付きとラベル無しタプルの代入
ラベル付きとラベル無しのタプルはお互いに代入できます。
let tuple1: (Int, Int) = (int1: 1, int2: 2)
let tuple2: (int1: Int, int2: Int) = (1, 2)
しかしラベル名が異なっている場合は代入できません。
let tuple: (int1: Int, int2: Int) = (int3: 1, int4: 2) // エラー
Tupleを使った代入
Tupleを使うと複数の変数を同時に初期化する事ができます。
let (value0, value1) = (1, 2)
print(value0) // 1
print(value1) // 2
この性質を使えば複数の値を返すメソッドを作る事ができます。
func method() -> (Int, Int) {
return (1, 2)
}
let (value0, value1) = method()
print(value0)
print(value1)
2つの変数の値を入れ替える事もできます。
var value0 = 0
var value1 = 1
(value0, value1) = (value1, value0)
print(value0) // 1
print(value1) // 0
typealiasを使ってTupleに別名を付ける
Tupleにtypealiasで名前を付ける事もできます。
プロトタイプを作る際にEntityとして使うと
typealias MyTuple = (int: Int, str: String)
let tuple = MyTuple(int: 1, str: "AAA")
print(tuple)
しかしextensionで拡張をする事はできませんでした。
typealias MyTuple = (int: Int, str: String)
extension MyTuple {} // エラー
Tupleは値渡し
Tupleはstructやenumと同じで値渡しになります。
var tuple1 = (int: 1, str: "AAA")
let tuple2 = tuple1
tuple1.int = 10
print(tuple1) // (10, "AAA")
print(tuple2) // (1, "AAA")
要素が一つだけのTuple
要素が一つだけのTupleはTupleではなくなります。
let tuple1: (Int) = (1)
print(tuple1.dynamicType) // Int
要素が0個のTuple
メソッドの定義でよく出てくるVoidですが、実態は空タプルのAliasになります。
public typealias Void = ()
let closure: Void -> Void = {}
let closure: () -> () = {}