Help us understand the problem. What is going on with this article?

Swiftでクロージャ (Closure)を簡単にまとめてみる

More than 5 years have passed since last update.

概要

Swiftに限らず、そもそもクロージャって何?って感じで、クロージャの使いどころもわからないのだが、とりあえず頭の整理ということで、簡単に試しながら整理してみる。

クロージャって何?

個人的にではあるが、クロージャとはただ単に変数に代入された関数であると思っていた。
ちなみにAppleのSwiftのテキストには、下記のように定義されている。

{ (parameters) -> return type in
    statements
}

抜粋:: Apple Inc. “The Swift Programming Language”。 iBooks. https://itun.es/jp/jEUH0.l

正直言って、ますます余計にわからない。理解不能。

関数(function)との違い

まずは関数(function)とクロージャは何が違うのかを見てみる。まずは超簡単に普通のよくある関数を使ったHello World!!
どの言語を使っていたとしても、関数の使用については特にわからないことはないと思う。

その1

まずは、引数を取らないシンプルな関数。関数内ではprintln()で出力する。

//関数
func simpleFunc() {
    println("こんにちは。ほげさん")
}
simpleFunc()

そして、クロージャを使用して同じこと(同じ出力結果)を試してみる。

//クロージャ
var simpleClosure: () -> () = {
    println("こんにちは。ほげさん")
}
simpleClosure()

出力結果は同じはずである。
異なるのは、クロージャは、varで宣言しているので変数である。
そして、普通の変数と同様に、:() はその変数の型で、->()は戻り値の型である。
この例では、引数無し戻り値無しということである。引数がvoid。戻り値も voidという感じかな?

simpleClosure()でコールされている事がわかる。

その2

次に、引数をString型で渡し、String型を戻り値として返す関数。シンプルにするために、引数で渡されたparamをそのままreturnで返す。
関数の外でprintln()で出力する。

//String引数付関数
func paramFunc(param:String) -> String{
    return "こんにちは。" + param + "さん"
}
println(paramFunc("もく"))

そして、クロージャを使用して同じことを試してみる。

//String引数付クロージャ
var paramClosure: (String) -> String
//クロージャの実装
paramClosure = {
    p -> String in
    return "こんにちは。" + p + "さん"
}
println(paramClosure("もく"))

ここで理解できるのは、pはクロージャの引数で -> String型を返す。そして、in の後に、return する結果であるstatementsを返すということ。

ちなみに、「クロージャの実装」とコメントに記述してしまっているが、このような呼び方が正しいかどうかはわからない。
しかし理解を助ける上であえて「クロージャの実装」というコメントを記述してる。

これで、何となくであるが、AppleのSwiftのテキストに説明してあるクロージャの説明が理解できるようになる。

その3

ただ、このままだとまだまだクロージャの使いどころがわからない?
クロージャの何が嬉しいのか?何が美味しいのか?関数で良いんじゃないのか?

そこで、今度は、引数をInt型で2つ渡し、計算結果であるInt型を戻り値として返す関数。引数で渡されたp1p2を足し算してreturnで返す。
これも関数の外でprintln()で出力する。

//Int引数付関数
func intParamFunc(p1:Int, p2:Int)->Int{
    return p1 + p2
}
println(intParamFunc(2,6))

そして、クロージャを使用して同じことを試してみる。

//Int引数付クロージャ
var intParamClosure: (Int,Int) -> Int
//クロージャの実装
intParamClosure = {
    p1,p2 -> Int in
    return p1 + p2
}
println(intParamClosure(3,5))

ふ〜む。ここまでくるとかなり理解できている気になってきた。
とりあえず、深入りする前に今回はここまで。

Lovely Swift!!!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away