Swift - タプル(tuple)メモ

概要

  • 複数個のデータを組にしてまとめたもの。
  • 関数やプロパティから複数個の値をまとめて返却する際に良く使われる。

構造体との違い

メソッドやプロパティを付け加える事は出来ません。 タプルはPGM内でデータを渡したり、一時的に値を保持したりする用途で使うべきです。

代入

値型のデータで、代入によって新規のインスタンスが生成されます。

タプルを型とする変数にタプルを代入するには、互いの要素の個数と型が等しくないといけません。

let hoge = ("hoge1", "hoge2", "hoge3", 12345)
var fuga : (String, String, String, Int) = hoge

let hogefuga = ("hoge1", "hoge2")
fuga = hogefuga // error

タプルへのアクセス

タプルへアクセスする際は、「.」(ドット)と添字(0)の記法を用いてアクセスします。

let hoge = ("hoge1", "hoge2", "hoge3", 12345)
println("\(hoge.0)") // hoge1が出力

// タプルの中にタプルが含まれている場合
let fuga = ("hgoe1", ("hoge2", "hoge3"))
println("\(fuga.1.0)") // hoge2が出力

また、要素にラベル(キーワード)を付与することも出来ます。

let hoge = (first:"hoge1", second:"hoge2", third:"hoge3", fourth:12345)
println("\(hoge.first)") // hoge1が出力

キーワードを用いたタプルの代入

ただし、キーワード付きタプルの場合、代入処理には注意しないと行けません。 キーワード付きタプルの代入処理には以下の制約下じゃないと代入出来ません。

  • キーワードの内タプルへの代入
  • 同じキーワードのついたタプル

以下はそのサンプルです。

let hoge = ("hoge1", "hoge2", "hoge3")
let fuga = (first:"hoge1", second:"hoge2", third:"hoge3")
var assign1 : (String, String, String)
var assign2 : (first:String, second:String, third:String)
var assign3 : (st1:String, st2:String, st3:String)

assign1 = fuga // ok
assign2 = fuga // ok
assign3 = fuga // error!

キーワードがついたタプルの代入は、要素順じゃなくても問題ありません。

var hoge1, hoge2, hoge3
(first:hoge1, second:hoge2, third:hgoe3) = (third:"AAA", first:"BBB", second:"CCC")
var fuga: (first:String, second:String, third:String) = (third:"AAA", "BBB", "CCC") // BBB, CCC, AAAとなる

また、後述にあるswitch文内でキーワードを利用しても、キーワードは無視されます。

let hoge = (first:10, second:20)

switch hoge {
case (x:10, y: let y):
println("10, \(y)が指定されました")
case (first:_, second: let y):
println("ほげ")
default:
break
}
// 10, 20が指定されました が出力

タプルは2つのタプルが等しいか等の審議判定の機能は提供されていません

let hoge = ("hoge1", "hoge2", "hoge3", 12345)
var fuga = ("hoge1", "hoge2", "hoge3", 12345)

if hoge == fuga { // error!
println("true")
}

タプルから定数を作る

以下の用に記述する事で、定数を一気に作ることができます。

let hoge = (123, 456, 789)
let (num1, num2, num3) = hoge

println("\(num1), \(num2), \(num3)") // 123, 456, 789が出力

// 123の値しか必要じゃない場合
let (num4, _, _) = hoge
println("\(num4)")

タプルの型変換

let hoge = (first:100.0, second:200.0, third:300.0)
let fuga = hoge as (first:Int, second:Int, third:Int)
let fuga2 = hoge as (Int, Int, Int)

同時代入

var hoge1 = 100, hoge2 = 200
(hoge1, hoge2) = (hoge2, hoge1)
var hoge2 = (hoge1, hoge2)

タプルとswitch

let hoge = (1, 2)
switch hoge {
case (1,1):
println("ほげ")
case (1,2):
println("ふが")
case (1,3...10), (20, 21...30) // (1,3〜10), (20, 21〜30)の範囲
default:
break;
}

// ほげが出力

関数の戻り値にタプルを使う

func cal(x:Int, y:Int) -> (Int, Int, Int, Int) {
let plus = x + y
let minus = x - y
let multi = x * y
let div = x / y
return (plus, minus, multi, div)
}
let calResult = cal(10, 20)
println("\(calResult.0), \(calResult.1), \(calResult.2), \(calResult.3)")

戻り値をキーワード付きタプルにする

func cal(x:Int, y:Int) -> (plus:Int, minus:Int, multi:Int, div:Int) {
let plus = x + y
let minus = x - y
let multi = x * y
let div = x / y
return (plus, minus, multi, div)
}
let calResult = cal(10, 20)
println("\(calResult.plus), \(calResult.minus), \(calResult.multi), \(calResult.div)")

小技

switch + タプルで定数生成

let hoge = (2, 2)

switch (hoge) {
let hoge = (1, 2)
switch hoge {
case (1,1):
println("ほげ")
case (1,2):
println("ふが")
case (1,3...10), (20, 21...30) // (1,3〜10), (20, 21〜30)の範囲
println("ほげほげ")
case (2, let fuga)
println("2,\(fuga)が指定されました。")
default:
break
}

// 2,2が指定されました が出力
}

switch + タプル + where

let hoge = (2, 20)

switch hoge {
case (1, let x) where x > 10:
println ("1, 10以上")
case (2, let y) where x >= 20:
println("2, 20以上")
default:
break
}
// 2,20以上 が出力

タプルのtypealias

typealias HogeType = (first:String, second:String, third:String)
var fuga:HogeType = ("hgoe1", "hoge2", "hoge3")
println(fuga.first) // hoge1が出力