見出し画像

今でしょ!Swift - クロージャ -1

クロージャは名前付き関数を作成せずに一緒に実行するコードをグループして使えるようにしたものです。

クロージャは、定数と変数への参照を、それらを定義した定数、変数などからキャプチャ(取得)して保持し、スコープ内で使えます。

Swift のクロージャは、、コード内で機能の独立したブロックとして使うことができ、他のプログラミング言語と同じように使えます。

クロージャは、次の 3 つの形式のいずれか(関数もクロージャの一つ)

・グローバル関数は、名前があり値をキャプチャしないクロージャ
・ネスト関数は、名前があり、関数の中にある関数から値を取得できるクロージャ
・クロージャ式は、周囲の定義した定数、変数から値をキャプチャでき、軽量な構文で書かれた名前のないクロージャ

Swift のクロージャは、一般的に、簡潔で、混乱のない構文で書くことができるように最適化された、すっきりした明確なスタイルを備えています。最適化には次のものが含まれます。

・パラメータと戻り値の型を推論します
・単一式のクロージャは return キーワードなしで暗黙のリターンをします
・引数名を省略することができます
・末尾クロージャ構文を使用することができます

クロージャ式(Closure Expressions)

クロージャ式は、簡潔で明瞭にインラインのクロージャを記述する方法で、明確さや意図を失うことなく、省略、最適化した形式で記述できます。

下記に出てくるクロージャ式は、複数回使用される sorted(by:) メソッドを、最適化してより簡潔なものに改良した例です。

ソートメソッド

Swift の標準ライブラリで、sorted(by:) と呼ばれる指定した方法で並び替えるメソッドがあります。型、元の配列については変更しません。

下記のクロージャ式の例では、sorted(by:) メソッドを使用して、String の配列をアルファベットの逆順で並べ替えています。並べ替える初期配列は次のとおりです。

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

backward関数は隣同士の数値について定義してあり、s1>s2で順序は逆に、Boolで真偽値で判定していく形となっています。以下この関数を使って逆順にソートします。

func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
}
var reversedNames = names.sorted(by: backward)
// `reversedNames` は ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

クロージャ式構文

backward(_:_:) 関数のクロージャ式バージョン。

reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
    return s1 > s2
})

1 行で。

reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )

型の推論

戻り矢印(->)とパラメータ名を囲む括弧も省略できます。

reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )

return キーワードを省略して結果を暗黙的に返すことができます。

単一式のクロージャの暗黙的リターン

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

省略引数名

in キーワードは省略

reversedNames = names.sorted(by: { $0 > $1 } )

演算子メソッド

実際には、上記のクロージャ式を記述するさらに短い方法があります。Swift の String 型は、String 型の 2 つのパラメータを持ち、Bool 型の値を返す、文字列固有の大なり演算子(>)のメソッドを定義しています。これは、sorted(by:) メソッドに必要な型と完全に一致しています。したがって、> 演算子を渡すだけで、Swift は文字列固有の実装を使用していると推論できます。

reversedNames = names.sorted(by: >)




いいなと思ったら応援しよう!