Objective-C の block と同様 Swift の Closure も様々な利用シーンがあります。
それぞれの書き方をまとめました。
Objcetive-Cのまとめはこちらです。
(いまさら)Objective-C ブロックの書き方まとめ
メソッドのパラメータ / 戻り値 を closure にする(宣言時)
宣言時は呼び出し時と違い、戻り値がない場合でも-> Void
を書いてやる必要があります。
そうしないとclosure
として認識されません。
swift
// パラメータ / 戻り値がない closure
// () -> Void のひとかたまりが closure の型を表しています
func hasNothingMethod(closureName: () -> Void) -> () -> Void {
// do something
}
// パラメータ / 戻り値がある closure
// こちらの場合は (Int, Float) -> Bool が closure の型になります
func hasParamMethod(closureName: (Int, Float) -> Bool) -> (Int, Float) -> Bool {
// do something
}
メソッドのパラメータ / 戻り値 を closure にする(呼び出し時)
swift
// パラメータ / 戻り値がない closure
// パラメータを記述する() や closure の記述 () -> Void が省略化です
hasNothingMethod {
// do something
}
// パラメータ / 戻り値がある closure
hasParamMethod { (intValue: Int, floatValue: Float) -> Bool in
return Float(intValue) == floatValue
}
ローカル変数宣言
swift
var someClosure: ((Int, Float) -> Bool)
typealias
swift
// このように名前をつけることで、closureType をメソッドのパラメータの型などに使えるようになります。
typealias closureType = ((Int,Float) -> Bool)
使い方例
上の書き方を組み合わせただけですが、使い方の例を示します。
1. パラメータ / 戻り値がない closure
呼び出し時にはパラメータを記述する()
や closure の記述 () -> Void
が省略できるところが肝です。
playground
// パラメータ / 戻り値が closure であるメソッドを宣言
func hasNothingMethod(closureName: () -> Void) -> () -> Void {
return closureName // パラメータの closure をそのまま return する
}
// 上記メソッドに closure を渡して呼び出し、戻り値を取得
let returnedClosure = hasNothingMethod {
print("hasNothingMethod() に closure を渡しています")
}
// 戻り値の closure を実行
returnedClosure()
2. パラメータ / 戻り値がある closure
ちょっとわかりづらいですが、 hasParamMethod
の戻り値を格納した returnedClosure
を直後に実行しています。
playground
// パラメータ / 戻り値が closure であるメソッドを宣言
func hasParamMethod(closureName: (Int, Float) -> Bool) -> (Int, Float) -> Bool {
return closureName // パラメータの closure をそのまま return する
}
// 上記メソッドに closure を渡して呼び出し、戻り値を取得
let returnedClosure = hasParamMethod { (intValue: Int, floatValue: Float) -> Bool in
return Float(intValue) == floatValue
}
// 戻り値の closure を実行して、結果を print
print("結果は", returnedClosure(10, 10.1)) // 結果は false
3. パラメータ / 戻り値がある closure (typealiasを使った場合)
(Int, Float) -> Bool
を closureType
で置き換えた場合です。
2. の例とやっていることは同じですが、より見通しがよくなることがわかると思います。
playground
typealias closureType = (Int, Float) -> Bool
// パラメータ / 戻り値が closure であるメソッドを宣言
// closure の型は closureType
func hasParamMethod(closureName: closureType) -> closureType {
return closureName
}
// 上記メソッドに closure を渡して呼び出し、戻り値を取得
let returnedClosure: closureType = hasParamMethod { (intValue: Int, floatValue: Float) -> Bool in
return Float(intValue) == floatValue
}
// 戻り値の closure を実行して、結果を print
print("結果は",returnedClosure(10, 10.0)) // 結果は true
Objective-C の block と違い、使うシーンによって記述がほとんど変わらないので、格段に書きやすくなっています。
closure を活用しましょう!!