Swift-Closures
Swift4のクロージャは、ブロックとして編成され、C言語やObjective C言語のような任意の場所で呼び出される自己完結型関数のクロージャと似ています。 関数内で定義された定数および変数参照は、キャプチャされ、クロージャに格納されます。 関数はクロージャの特殊なケースとみなされ、次の三つの形式を取ります−
グローバル関数 | 入れ子関数 | クロージャ式 |
---|---|---|
名前を持っています。 値をキャプチャしない | には名前があります。 囲む関数 | からの値のキャプチャ名前のないクロージャは、隣接するブロックから値をキャプチャします |
Swift4言語のクロージャ式は、crisp、最適化、および軽量な構文スタイルに従います。
- コンテキストからパラメータと戻り値の型を推論します。
- 単一式クロージャからの暗黙的な戻り値。
- 省略形引数名と
- 末尾のクロージャ構文
構文
以下は、パラメータを受け取り、データ型を返すクロージャを定義するための一般的な構文です−
{ (parameters) −> return type in statements}
以下は簡単な例です−
let studname = { print("Welcome to Swift Closures") }studname()
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
Welcome to Swift Closures
次のクロージャは、二つのパラメータを受け入れ、Bool値を返します−
{ (Int, Int) −> Bool in Statement1 Statement 2 --- Statement n}
以下は簡単な例です−
let divide = { (val1: Int, val2: Int) -> Int in return val1 / val2 }let result = divide(200, 20)print (result)
playgroundを使用して上記のプログラムを実行すると、 次の結果−
10
クロージャ
ネストされた関数の式は、コードブロックの名前付けと定義の便利な方法を提供します。 関数宣言と名前構造全体を表す代わりに、短い関数を示すために使用されます。 フォーカスされた構文を持つ明確な簡単な文で関数を表すことは、クロージャ式によって実現されます。
昇順プログラム
文字列のソートは、標準ライブラリで既に利用可能なSwift4sキー予約関数”sorted”によって実現されます。 この関数は、指定された文字列を昇順でソートし、古い配列に記載されているのと同じサイズとデータ型を持つ新しい配列の要素を返します。 古い配列は同じままです。
sorted関数内では二つの引数が表現されています−
-
配列として表される既知の型の値。
-
配列の内容(Int、Int)を返し、ブール値(Bool)を返します配列が適切にソートされている場合はtrue値を返しますそれ以外の場合はfalseを返します。
入力文字列を持つ通常の関数が書き込まれ、sorted関数に渡され、以下に示す新しい配列にソートされた文字列を取得します−
func ascend(s1: String, s2: String) -> Bool { return s1 > s2}let stringcmp = ascend(s1: "Swift 4", s2: "great")print (stringcmp)
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
true
アイスクリームのためにソートされる最初の配列は、”Swift4″と”great”として与えられます。 配列をソートする関数は文字列データ型として宣言され、その戻り値の型はBooleanとして言及されます。 両方の文字列が比較され、昇順でソートされ、新しい配列に格納されます。 ソートが正常に実行された場合、関数はtrue値を返し、それ以外の場合はfalseを返します。
クロージャ式の構文は次のように使用します−
- 定数パラメータ、
- 変数パラメータ、および
- inoutパラメータ。
クロージャ式はデフォルト値をサポートしていませんでした。 可変長引数とタプルは、パラメータ型と戻り値の型としても使用できます。
let sum = { (no1: Int, no2: Int) -> Int in return no1 + no2 }let digits = sum(10, 20)print(digits)
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
30
functionステートメントに記載されているパラメータと戻り値の型宣言は、’in’キーワードを持つインラインクロージャ式関数で表すこともできます。 一度宣言するパラメータと戻り値の型’in’キーワードは、クロージャの本体を示すために使用されます。
Single Expression Implicit Returns
ここで、ソートされた関数の第二引数の関数型は、bool値がクロージャによって返されなければならないことを明確にします。 クロージャの本体には、Bool値を返す単一の式(s1>s2)が含まれているため、あいまいさはなく、returnキーワードは省略できます。
式クロージャで単一の式ステートメントを返すには、’return’キーワードは、その宣言部分で省略されています。
var count: = let descending = count.sorted(by: { n1, n2 in n1 > n2 })let ascending = count.sorted(by: { n1, n2 in n1 < n2 })print(descending)print(ascending)
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
文自体は、string1がstring2より大きい場合はtrueを返すことを明確に定義しています。
既知の型クロージャ
二つの数の加算を考えてみましょう。 私たちは、加算が整数データ型を返すことを知っています。 したがって、既知の型クロージャは次のように宣言されます−
let sub = { (no1: Int, no2: Int) -> Int in return no1 - no2 }let digits = sub(10, 20)print(digits)
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
-10
短縮引数名をクロージャ
として宣言すると、Swift4は自動的にインラインクロージャに短縮引数名を提供します。Swift0、$1、2 2などの名前でクロージャの引数の値を参照するために使用できます。
var shorthand: (String, String) -> Stringshorthand = { }print(shorthand("100", "200"))
ここで、closure0と$1はクロージャの第一および第二の文字列引数を参照します。
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
200
Swift4は、インラインクロージャを省略形の引数名として表現することを容易にします$0, $1, $2 — $n.
クロージャ引数リストは、クロージャ式の中で省略された引数名を表す場合、定義セクションでは省略されます。 関数の型に基づいて、省略形の引数名が導出されます。 省略形引数は式の本文で定義されているため、’in’キーワードは省略されます。
演算子関数としてのクロージャ
Swift4は、演算子関数をクロージャとして提供するだけで、メンバーに簡単にアクセスする方法を提供します。 前の例では、キーワード’Bool’は、文字列が等しい場合に’true’を返すために使用され、それ以外の場合は’false’を返します。
式は、クロージャ内の演算子関数によってさらに簡単になります−
let numb = var sortedNumbers = numb.sorted ({ (left: Int, right: Int) -> Bool in return left < right})let asc = numb.sorted(<)print(asc)
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
Closures As Trailers
関数の最後の引数をクロージャ式に渡すことは、’Trailing Closures’の助けを借りて宣言されます。 これは、関数()の外側に{}で書かれています。 その使用法は、関数を一行にインラインで書くことができない場合に必要です。
reversed = sorted(names) { > }
ここで、{0 0>$1}は、外部(名前)で宣言された末尾のクロージャとして表されます。
import Foundationvar letters = let twoletters = letters.map({ (state: String) -> String in return state.substringToIndex(advance(state.startIndex, 2)).uppercaseString})let stletters = letters.map() { .substringToIndex(advance(.startIndex, 2)).uppercaseString }print(stletters)
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
値と参照型のキャプチャ
Swift4では、定数と変数の値のキャプチャはクロージャの助けを借りて行われます。 さらに、変数が存在しなくなった場合でも、クロージャ本体内のこれらの定数と変数の値を参照して変更します。
定数値と変数値のキャプチャは、他の関数の本体にfunction withを書き込むことによって入れ子関数を使用することによって達成されます。
ネストされた関数がキャプチャします−
- 外部関数の引数。
- 外部関数内で定義された定数と変数をキャプチャします。
Swift4では、定数または変数が関数内で宣言されると、その変数への参照もクロージャによって自動的に作成されます。 また、次のように、2つ以上の変数を同じクロージャとして参照する機能も提供します−
let decrem = calcDecrement(forDecrement: 18)decrem()
ここで、oneDecrement変数とDecrement変数は、両方ともクロージャ参照と同じメモリブロックを指します。
func calcDecrement(forDecrement total: Int) -> () -> Int { var overallDecrement = 100 func decrementer() -> Int { overallDecrement -= total print(overallDecrement) return overallDecrement } return decrementer}let decrem = calcDecrement(forDecrement: 18)decrem()decrem()decrem()
playgroundを使用して上記のプログラムを実行すると、次の結果が得られます−
826446
外側の関数calcDecrementが呼び出されるたびにdecrementer()関数が呼び出され、値を18ずつ減少させ、外側の関数calcDecrementの助けを借りて結果を返します。 ここでは、calcDecrementは閉鎖として機能します。
関数decrementer()に引数がない場合でも、デフォルトではclosureは既存の値をキャプチャすることによって変数’overallDecrement’と’total’を参照します。 指定された変数の値のコピーは、新しいdecrementer()関数で格納されます。 Swift4は、変数が使用されていないときにメモリ空間を割り当てたり割り当てたりして、メモリ管理関数を処理します。