クロージャ(Closures)ってなんだか色々書き方あってややこしいですよね。
というわけで整理してみます。
想定読者
- Swiftの基本的な文法はなんとなく理解しているが、クロージャはややこしいな、という人
- Swiftはある程度書けるようになったけど、いまいちクロージャの書き方に自信がない人
- 他言語でプログラミング経験があり、これからSwiftを学びたい人
クロージャとは
Closures are self-contained blocks of functionality that can be passed around and used in your code.
Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.
クロージャは、コードの中で渡したり使用したりすることができる自己完結型の機能ブロックです。
Swiftのクロージャは、CやObjective-Cのブロックや他のプログラミング言語のラムダに似ています。
クロージャの書き方
基本構文(全部盛り)
まずはこれをしっかりと覚えると、後に紹介する省略記法が理解しやすくなります。
{ (引数名1: 型, 引数名2: 型...) -> 戻り値の型 in
実行するコード...
}
例
// 定義
let intToString = { (a: Int, b: Int) -> String in
return "\(a)と\(b)です"
}
// 利用する
let sample1 = intToString(1, 5)
print(sample1) // 1と5です
省略
型表記
型が推論できるケースでは、引数や戻り値の型表記を省略できます。
- 型が推論できるケース
- 代入する変数の型が明確
- 関数の引数(関数定義で明確に記載される)
// 代入する変数の型が明確
var sample2: ((Int, Int) -> String)
// 引数の()も省略可能
sample2 = { a, b in
return "\(a)と\(b)です"
}
print(sample2(2, 3)) // 2と3です
return
クロージャ内の文がひとつしかない場合は return
省略可能
// return省略
let intToString = { (a: Int, b: Int) -> String in
"\(a)と\(b)です"
}
下記コードはコンパイルエラーとなります。
// 2つ以上文があると省略不可
let sum = { (a: Int, b: Int) -> Int in
let sum = a + b
sum
}
// ;で1行にしてもダメ
let sum = { (a: Int, b: Int) -> Int in
let sum = a + b; sum
}
Shorthand Argument Names
型表記を省略できるケースでは、さらに引数名も省略可能です。
Shorthand Argument Names
は $
に引数のindexを合わせ、$0
や $1
と記載します。
// 引数名も省略可能
// 型の表記も省略 -> in も省略しないとコンパイルエラー
sample2 = {
"\($0)と\($1)です"
}