コンユウメモ @kon_yu

作ったガラクタとか、旅行とかの話

クロージャを引数としたメソッド記法の整理

UIAlertActionをインスタンス化するサンプルコードが、定義されているコンストラクタ

public convenience init(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void)?)

と違って引数のhandlerが括弧の外に書くようになっていたので気になって、クロージャを引数に取るメソッドの書き方調べた。

この書き方を、詳解Swiftでは「末尾クロージャ」とという項に書いてあり、

AppleSwiftのlanguage guide では「Trailing Closures」に記されている

注意

  • 勉強中なので情報は間違っている可能性があります
  • 動作確認: Swift2.0
func function1(handler: ()->Void) {
    handler()
    print("this is function1!!!")

}
// クロージャを引数として渡す
let closure = {
    print("this is closure!!!")
}

function1(closure)
//=> this is closure!!!
//   this is function2!!!


func function2(){
    print("this is function2!!!")
}

function2()
// => this is function1!!!


// メソッドとクロージャの引数として渡せる
function1(function2)

//=> this is function1!!!
//   this is function2!!!

// クロージャを直接引数として渡す
function1({
    print("inside")
})
//=> inside
//   this is function2!!!


// クロージャを直接引数とする場合は括弧()の外でOK
// クロージャの引数が一番最後の時のみ
function1(){
    print("outside")
}
//=> outside
//   this is function2!!!

// つまり
// この最後がクロージャが引数の場合はOKで
//  末尾クロージャ/Trailing Closuresの書き方がこれ
func function3(arg1: String, handler: ()->Void) {
    handler()
    print("this is \(arg1)!!!")
}
function3("arg1 string"){ print("arg1 handler")}


// こちらの第二引数がクロージャの場合にはエラーになる
func function4(arg1: String, handler: ()->Void, arg2: String) {
    handler()
    print("this is \(arg1), \(arg2)!!!")
}

function4("arg1", handler: { print("arg1 handler")},arg2: "arg2 string")
//=> arg1 handler
//   this is arg1, arg2 string!!!

// よってこう書くとエラーになる
//function4("aaa", arg2: "arg2 string"){ print("arg1 handler")}

オススメSwift技術書

詳解 Swift 改訂版

詳解 Swift 改訂版

Swiftポケットリファレンス

Swiftポケットリファレンス