ミライスタート TECH系ブログ

株式会社ミライスタートのエンジニア達が気になったTECH系の記事等をアップしています!

【swift2.2】【備忘】クロージャー①

こんばんは、石井です。

VB6歴の長い私から見ると、
今まで備忘に書いてきたことすべてが未知の領域ですが、
クロージャーはswiftでの使用頻度が高いので
特に気になる関心ごとの一つです。


関数の書き方を崩したような記法になります。

▪️書き方①(しっかり書いた場合)

{ (パラメーター) -> return 返却型 in
    ステートメント
}

サンプル

  func closureTest(closure:(Int,Int)->Int, val1:Int, val2:Int) -> Int{ //クロージャーを引数で受け取る関数
    return closure(val1,val2)
  }

  func disp(){
    let p1 = closureTest({(val1:Int,val2:Int) -> Int in return val1+val2 },val1: 1,val2: 2) //クロージャーを引数に渡す
    print(p1)
  }

期待してたclosureの引数の数が違った場合、以下のエラーが表示される。
Contextual closure type '(Int, Int, Int) -> Int' expects 3 arguments, but 2 were used in closure body

▪️書き方②(省略できる)

func closureTest(closure:(Int,Int)->Int, val1:Int, val2:Int) -> Int{
クロージャーの引数の型が宣言されているため型推論が働くので、
以下のサンプルのように引数と戻り値の型を書く必要がなくなる。

サンプル

  func disp(){
    let p1 = closureTest({ val1,val2 in return val1+val2 },val1: 1,val2: 2)
    print(p1)
  }

ちなみに、Int型を期待しているところにString型の戻り値が入ると以下のエラーとなる。
Cannot invoke initializer for type 'String' with an argument list of type '(Int)'


▪️書き方③(単一表現の場合、さらに省略できる)
val1+val2を返却するのが解りきっているので、
returnの記載も不要になる。

  func disp(){
    let p1 = closureTest({ val1,val2 in val1+val2 },val1: 1,val2: 2)
    print(p1)
  }


書き方にバリエーションがあるので、
初見だと混乱しそうですね。

まだ省略した書き方があるので、これはまた次回。