【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