Swift-クロージャー

Swift 4のクロージャは、ブロックとして編成され、C言語やObjectiveC言語のようにどこでも呼び出される自己完結型関数のクロージャに似ています。関数内で定義された定数と変数参照はキャプチャされ、クロージャに格納されます。関数はクロージャの特殊なケースと見なされ、次の3つの形式を取ります-

グローバル関数 入れ子関数 クロージャー式
名前を付けてください。値をキャプチャしないでください 名前を付けてください。囲んでいる関数から値をキャプチャする 名前のないクロージャは、隣接するブロックから値をキャプチャします

Swift 4言語のクロージャー式は、を含む鮮明で最適化された軽量の構文スタイルに従います。

  • コンテキストからパラメータと戻り値の型を推測します。
  • 単一式クロージャからの暗黙的な戻り。
  • 省略引数名と
  • 末尾のクロージャ構文

構文

以下は、パラメーターを受け入れてデータ型を返すクロージャを定義するための一般的な構文です。

{
   (parameters) −> return type in
   statements
}

以下は簡単な例です-

let studname = { print("Welcome to Swift Closures") }
studname()

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

Welcome to Swift Closures

次のクロージャは2つのパラメータを受け入れ、ブール値を返します-

{     
   (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)

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

10

クロージャ内の式

入れ子関数は、コードのブロックに名前を付けて定義する便利な方法を提供します。関数宣言全体を表す代わりに、名前の構成を使用して短い関数を示します。焦点を絞った構文を使用して明確な簡潔なステートメントで関数を表すことは、クロージャー式によって実現されます。

昇順プログラム

文字列のソートは、標準ライブラリですでに利用可能なSwift4sキー予約関数「sorted」によって実現されます。この関数は、指定された文字列を昇順で並べ替え、古い配列に記載されているのと同じサイズとデータ型の新しい配列の要素を返します。古い配列は同じままです。

ソートされた関数内に2つの引数が表されます-

  • 配列として表される既知のタイプの値。

  • 配列の内容(Int、Int)であり、配列が適切にソートされている場合はブール値(Bool)を返し、そうでない場合はfalseを返します。

入力文字列を含む通常の関数が書き込まれ、sorted関数に渡されて、文字列が次のように新しい配列に並べ替えられます。

func ascend(s1: String, s2: String) -> Bool {
   return s1 > s2
}

let stringcmp = ascend(s1: "Swift 4", s2: "great")
print (stringcmp)

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

true

アイスクリーム用にソートされる最初の配列は、「Swift4」および「great」として指定されます。配列をソートする関数は文字列データ型として宣言され、その戻り値の型はブール値として示されます。両方の文字列が比較され、昇順で並べ替えられ、新しい配列に格納されます。ソートが正常に実行された場合、関数はtrue値を返し、そうでない場合はfalseを返します。

クロージャ式の構文は-を使用します

  • 定数パラメータ、
  • 可変パラメータ、および
  • inoutパラメータ。

クロージャ式はデフォルト値をサポートしていませんでした。可変個引数パラメーターとタプルは、パラメーターの型と戻り値の型としても使用できます。

let sum = {
   (no1: Int, no2: Int) -> Int in 
   return no1 + no2 
}

let digits = sum(10, 20)
print(digits)

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

30

関数ステートメントで言及されているパラメーターと戻り値の型の宣言は、「in」キーワードを使用したインラインクロージャ式関数で表すこともできます。パラメータと戻り値の型を宣言すると、 'in'キーワードは、クロージャの本体であることを示すために使用されます。

単一式の暗黙的なリターン

ここで、ソートされた関数の2番目の引数の関数タイプは、Bool値がクロージャーによって返される必要があることを明確にしています。クロージャーの本体には、ブール値を返す単一の式(s1> s2)が含まれているため、あいまいさはなく、returnキーワードは省略できます。

式クロージャで単一の式ステートメントを返すには、宣言部分で「return」キーワードを省略します。

var count:[Int] = [5, 10, -6, 75, 20]
let descending = count.sorted(by: { n1, n2 in n1 > n2 })
let ascending = count.sorted(by: { n1, n2 in n1 < n2 })

print(descending)
print(ascending)

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

[75, 20, 10, 5, -6]
[-6, 5, 10, 20, 75]

ステートメント自体は、string1がstring 2より大きい場合はtrueを返し、それ以外の場合はfalseを返すことを明確に定義しているため、ここではreturnステートメントを省略しています。

既知のタイプのクロージャ

2つの数字の加算を検討してください。加算によって整数データ型が返されることがわかっています。したがって、既知の型クロージャは次のように宣言されます-

let sub = {
   (no1: Int, no2: Int) -> Int in 
   return no1 - no2 
}

let digits = sub(10, 20)
print(digits)

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

-10

短縮引数名をクロージャーとして宣言する

Swift 4は、インラインクロージャに短縮引数名を自動的に提供します。これを使用して、クロージャの引数の値を$ 0、$ 1、$ 2などの名前で参照できます。

var shorthand: (String, String) -> String
shorthand = { $1 }
print(shorthand("100", "200"))

ここで、$ 0と$ 1は、クロージャーの最初と2番目の文字列引数を参照します。

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

200

Swift 4は、$ 0、$ 1、$ 2 --- $ nを表すことにより、ユーザーがインラインクロージャを省略引数名として表すのを容易にします。

クロージャ式内で短縮引数名を表す場合、定義セクションではクロージャ引数リストが省略されます。関数タイプに基づいて、省略引数名が導出されます。省略引数は式本体で定義されているため、「in」キーワードは省略されています。

演算子関数としてのクロージャ

Swift 4は、演算子関数をクロージャーとして提供するだけで、メンバーにアクセスする簡単な方法を提供します。前の例では、キーワード「Bool」を使用して、文字列が等しい場合は「true」を返し、それ以外の場合は「false」を返します。

式は、クロージャの演算子関数によってさらに単純になります。

let numb = [98, -20, -30, 42, 18, 35]
var sortedNumbers = numb.sorted ({
   (left: Int, right: Int) -> Bool in
   return left < right
})

let asc = numb.sorted(<)
print(asc)

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

[-30, -20, 18, 35, 42, 98]

トレーラーとしての閉鎖

関数の最後の引数をクロージャ式に渡すことは、「TrailingClosures」の助けを借りて宣言されます。関数()の外に{}を付けて記述されています。関数を1行でインラインで記述できない場合に使用する必要があります。

reversed = sorted(names) { $0 > $1}

ここで、{$ 0> $ 1}は、外部(名前)で宣言された末尾のクロージャとして表されます。

import Foundation
var letters = ["North", "East", "West", "South"]

let twoletters = letters.map({ 
   (state: String) -> String in
   return state.substringToIndex(advance(state.startIndex, 2)).uppercaseString
})

let stletters = letters.map() { 
   $0.substringToIndex(advance($0.startIndex, 2)).uppercaseString 
}
print(stletters)

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

[NO, EA, WE, SO]

値と参照型の取得

Swift 4では、定数と変数の値のキャプチャはクロージャの助けを借りて行われます。さらに、変数が存在しなくなった場合でも、クロージャー本体内の定数と変数の値を参照および変更します。

定数値と変数値の取得は、他の関数の本体に関数を記述してネストされた関数を使用することで実現されます。

入れ子関数は-をキャプチャします

  • 外部関数の引数。
  • Outer関数内で定義された定数と変数をキャプチャします。

Swift 4では、定数または変数が関数内で宣言されると、その変数への参照もクロージャーによって自動的に作成されます。また、次のように3つ以上の変数を同じクロージャとして参照する機能も提供します。

let decrem = calcDecrement(forDecrement: 18)
decrem()

ここに oneDecrement デクリメント変数は両方とも、クロージャ参照と同じメモリブロックを指します。

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()

遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

82
64
46

外部関数calcDecrementが呼び出されるたびに、decrementer()関数が呼び出され、値が18ずつ減少し、外部関数calcDecrementを使用して結果が返されます。ここで、calcDecrementはクロージャとして機能します。

関数decrementer()には引数がありませんが、デフォルトでは、クロージャは既存の値をキャプチャすることによって変数 'overallDecrement'および 'total'を参照します。指定された変数の値のコピーは、新しいdecrementer()関数で保存されます。Swift 4は、変数が使用されていないときにメモリスペースを割り当てたり、割り当てを解除したりすることで、メモリ管理機能を処理します。