KOSEN{BLOG}について

0から学ぶClosure ~Learn Swift for Beginners~

0から学ぶClosure

 

一般的な関数では変数を引数として変数を戻り値とします.

Closureは関数を引数として関数を戻り値とします.

よく説明されるClosureの認識ですが,{ }を使ったらClosureという認識が強いと思います.

今回はその認識を100%わかるように0からClosureを説明していきたいと思います.

 


Closureの定義の前に復習

 

引数があり戻り値もある関数は,以下のように表されます.

func functionName(parameter: parameterType) -> returnType{
  //色々処理
    return output
}

これらはどんな言語でも共通していることです.

parameterTypeに何かしらのインプットを行いreturnTypeでアウトプットします.

ここでわからない人は,関数の記事を書いたのでそちらを参考にしてください.

関数の3つの定義 ~Learn Swift for Beginners~

 


Closureの起源

まず,足し算を行う関数を考えてみましょう.

func calc(num1:Int,num2:Int) -> Int {
    return num1 + num2
}


calc(num1: 2, num2: 5)
//return 7

引数と戻り値がある関数の定義から計算を行なっています.

これがClosureとどんな関係があるのでしょうか?

 

calc関数の足し算を掛け算に変えてみましょう

func multiply(num1:Int,num2:Int) -> Int {
    return num1 * num2
}


calc(num1: 2, num2: 5)
//return 10

 

はい.この関数は,形を変えずに処理だけを変えることができています.

func

 

ではこれらのcalc関数に足し算か掛け算を指定できるような関数を作れそうな気がしてきました?

これがClosureを含んだ関数の書き方

func calc(n1:Int,n2:Int,operation:(Int,Int)->Int) -> Int {
    return operation(n1,n2)
}

新しく計算の引数を付け加えました.

operationには(Int,Int) の引数と戻り値がIntの関数を代入することができます.

そしてcalc関数にoperationを戻り値に設定することができます.

Closureとなりうる関数

func add(n1: Int, n2: Int) -> Int {
    return n1 + n2
}

func multiply(n1:Int,n2:Int) -> Int {
    return n1 * n2
}

operationにいれる関数これこそがClosureとなりうる関数です.


 

名前のある関数を使ってのClosure

いきなり無名関数を扱っても分かりにくいので名前のある関数を作成してそれをClosureに代入してみましょう.

 

func add(num1:Int,num2:Int) -> Int {
    return num1 + num2
}

func multiply(num1:Int,num2:Int) -> Int {
    return num1 * num2
}

注意
それぞれ引数の型,戻り値の型が同じであることが大切

どちらも(Int,Int) の引数と戻り値がIntの関数になっていますよね?

 

calc(num1:Int, num2:Int, operation:(Int, Int) -> Int)

calc

これらを計算してみると,

 

calc(n1: 2, n2: 5, operation: add)
//return 7
calc(n1: 2, n2: 5, operation: multiply)
//return 10

引数にadd や multiplyを入れることで関数を実行することができました.

しかし,かなりコードを書きましたね.これはまだ未完成のClosureです.

Closureは無名関数などと言われていますが,今のところ名のある関数しか実行していません.😅今からより簡潔に書く方法の紹介をします。

無名関数を扱ったClosure

 

では今からClosureの威力を見ていきましょう.

Closureのルールを説明します.

有名の関数を代入しましたが,今から無名の関数に変化させたいと思います.


有名→無名関数に変化させるルール

名のある関数を無名関数に変化させたいと思います.

いくつかルールがあるのでそのルールに沿って変化させたいと思います.

  • 関数のfunc addの文字を削除
  •  { を関数の初めに持ってくる.
  • outputの型の右に in を入れる.

 

これがClosure

この無名関数をcalc関数に入れてみると.

calc(n1: 2, n2: 5, operation: {(num1:Int,num2:Int) -> Int in
    return num1 + num2
})

これでClosureを使った式になりました.

しかし,これでは Closureの恩恵が少ないです.これをもっと省略してみましょう.

省略ルール1

第二形態

calc(n1: 2, n2: 5, operation: {(num1,num2)in num1 + num2})

一行!!!

注意
calc関数は最初に定義したものです.変更したのはoperationに入れる関数の形

ルールとしては,calc関数に引数と返り値の型は指定してあるのでClosure内で型を宣言する必要がないので消すことができます.


 

省略ルール2

 

そして二番目の省略のルール

ここまで来ればClosureは完璧でしょう.

Swiftでは、クロージャーは無名のパラメータ名を提供しています.

したがって、ここではパラメーター名としてnum1とnum2を指定していますが,

パラメータ名を無名にすることが可能なのでSwiftが準備しているパラメータ名

$を用いてパラメータ名を指定します.最初のパラメータを​

$0

二番目のパラメータを

$1

としています.

つまり例を示すと,

calc(n1: 2, n2: 5, operation: {$0 + $1})

 

そして後で、これらのパラメーター名を参照して式を実行します。

ただし、これを行う代わりに、実際には匿名パラメーター名を使用できます。


最後の省略のルール

Swiftには、関数の最後のパラメーターがClosureである時,そのパラメータを省略することができるといったルールがあります.

第四形態

 

これが最後のClosureです.全くもって美しい形になりました.

calc(n1: 2, n2: 5){$0 + $1}

Closureを書く前に()を閉じて{ Closure }を付け加えるだけで完成です.


いかがでしたか?Closureの凄さ伝わりましたか?

以上でClosureの説明を終わります.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です