【swift】 クロージャの使い方 (たぶんすっごく基本)
クロージャとは????
処理のひとかたまりで、名前のついていないメソッドのようなもの
変数に保存したり、メソッドの引数として渡すことで実行できたりする
使用例
- 変数に保存して利用する
- メソッドの引数に記載して利用する (トレイリングクロージャ) 【メイン】
※ 上記以外にもありそうですが、すっごく基本ということでこの程度にしておきます。。。
※ 本記事では個人的に体感よく見かけるトレイリングクロージャをメインに記載します
変数に保存して利用する
let sum = { (x: Int, y: Int) -> Int in
return x + y
}
// 引数名を指定しない
let a = sum(1, 2) // 3
簡単に解説 (多分引用元の方がわかりやすいと思います)
クロージャは下記の形式で記載します。
{ (引数名:引数の型) -> 戻り値の型 in
// 処理の実行
}
-
(x: Int, y: Int)の部分がクロージャの処理で使用する引数となっています。 -
-> Intの部分がクロージャで処理した結果の戻り値の型となります。 -
in以降に処理内容を記載します。
引用元:https://swift.codelly.dev/guide/クロージャ/#クロージャ式の引数
メソッドの引数に記載して利用する (トレイリングクロージャ)
実際に簡単なものを作って解説します
渡した先で処理を実行する
作ったもの
クロージャで渡した処理の結果をラベルに表示できるようにします

コード全体
// 与えた数値を足し算した後、labelとして表示する
showResult(x: 5, y: 2)
// labelとして表示するための処理は書いて、計算する処理 + 計算後の表示はplusにお願いしてる
func showResult(x: Int, y: Int) {
plus(x: x, y: y, complete: { sum in
label.text = String(sum)
})
}
// 受け取った値を足し算して、その後にcompleteの処理を実行してる
func plus(x: Int, y: Int, complete: (Int) -> Void) {
let sum = x + y
complete(sum)
}
結果

解説
showResultの呼び出し
この部分が処理の始まりです。
渡した引数2つの足し算が実行されるようにします。
// 与えた数値を足し算した後、labelとして表示する
showResult(x: 5, y: 2)
showResultの処理内容
showResultの処理内容です。
ここまでは普通のメソッドの使い方と変わらず、plusというメソッドを呼び出しているだけです。
ただ、plusの呼び出し方がいつもと違っています...
// labelとして表示するための処理は書いて、計算する処理 + 計算後の表示はplusにお願いしてる
func showResult(x: Int, y: Int) {
plus(x: x, y: y, complete: { sum in
label.text = String(sum)
})
}
plusの呼び出しについて
まず、普段よく使われるような基本の呼び出しの場合、下記のように「外部引数名: メソッドに渡す値」のように記載しています
func showResult(x: Int, y: Int) {
plus(x: x, y: y)
}
plus側でxの変数名で扱われているものにshowResultのxを、plus側でyの変数名で扱われているものに、showResultのyを渡しています。
次に今回のようにクロージャも渡しているパターンです。
// labelとして表示するための処理は書いて、計算する処理 + 計算後の表示はplusにお願いしてる
func showResult(x: Int, y: Int) {
plus(x: x, y: y, complete: { sum in
label.text = String(sum)
})
}
本来であればplus(x: x, y: y, complete: syori)と記載したいところを、syoriと記載されている部分を処理のひとかたまり(=クロージャ)に変えています。
plus(x: x, y: y, complete: {// ここに処理を記載する})
ただ、長くなってしまうとすごく見づらいので、改行して見やすいようにしています。
plus(x: x, y: y, complete: {
/// ここに処理を記載する
})
今回plusに渡している処理は、ラベルの値を計算結果になるように更新する処理を渡しています。
計算の処理が完了した後に、plusのメソッド内で更新まで実行してもらおうとしています。
plusの処理内容
showResultで呼び出された、plusの処理です。
こちらも普段と少し変わっている部分(complete: (Int) -> Void)があります。
// 受け取った値を足し算して、その後にcompleteの処理を実行してる
func plus(x: Int, y: Int, complete: (Int) -> Void) {
let sum = x + y
complete(sum)
}
complete: (Int) -> Voidに関して
ここは本来であれば、外部引数名: 型の形式で記載されることが基本かと思います。
func plus(x: Int, y: Int) {
let sum = x + y
}
そのため、complete: 型と記載したいところですが、クロージャの場合は型の代わりにクロージャの引数の型と戻り値の型を記載します。
今回は、計算結果(Int)を受け取って、処理を完了(戻り値なし = void)となっています。
// 受け取った値を足し算して、その後にcompleteの処理を実行してる
func plus(x: Int, y: Int, complete: (Int) -> Void) {
let sum = x + y
complete(sum)
}
(おまけ) 渡す先のメソッドが複数にまたがる場合
コード全体
// 与えた数値を足し算した後、10倍してlabelとして表示する
showResult(x: 5, y: 2)
// labelとして表示するための処理は書いて、計算する処理 + 計算後の表示はplusにお願いしてる
func showResult(x: Int, y: Int) {
plus(x: x, y: y, complete: { sum in
label.text = String(sum)
})
}
// 受け取った値を足し算して、10倍する処理 + 計算後の表示はtenTimesにお願いしてる
func plus(x: Int, y: Int, complete: (Int) -> Void) {
let sum = x + y
tenTimes(x: sum, complete: complete)
}
// 受け取った値を10倍したあと、completeの処理 (= labelに表示する処理)を実行する
func tenTimes(x: Int, complete: (Int) -> Void) {
let result = 10 * x
complete(result)
}
結果

解説
基本的には「渡した先で処理を実行する」の項目で解説したものと同じですが、
異なっているのがこの辺りになります。
// 受け取った値を足し算して、10倍する処理 + 計算後の表示はtenTimesにお願いしてる
func plus(x: Int, y: Int, complete: (Int) -> Void) {
let sum = x + y
tenTimes(x: sum, complete: complete)
}
// 受け取った値を10倍したあと、completeの処理 (= labelに表示する処理)を実行する
func tenTimes(x: Int, complete: (Int) -> Void) {
let result = 10 * x
complete(result)
}
plusで受けとったcompleteをtenTimesにそのまま渡しています。
showResultで渡したクロージャは、plusのcompleteの変数に格納された状態になっているため、そのままtenTimesに渡すことが可能です。
「変数に保存して利用する」のイメージに近いです。
Discussion