Swift-closures

提供:Dev Guides
移動先:案内検索

スイフト-クロージャー

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

Global Functions Nested Functions Closure Expressions
Have a name. Do not capture any values Have a name. Capture values from enclosing function Unnamed Closures capture values from the adjacent blocks

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

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

構文

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

{
   (parameters) −> return type in
   statements
}

以下は簡単な例です-

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

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Welcome to Swift Closures

次のクロージャは2つのパラメータを受け入れ、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)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

10

クロージャーの式

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

昇順プログラム

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

2つの引数は、ソートされた関数内で表されます-

  • 配列として表される既知のタイプの値。
  • 配列の内容(Int、Int)およびブール値(Bool)を返します。配列が適切にソートされている場合はtrue値を返し、そうでない場合はfalseを返します。

入力文字列を持つ通常の関数が書き込まれ、ソートされた関数に渡されて、以下に示す新しい配列にソートされた文字列を取得します-

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

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

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

true

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

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

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

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

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

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

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

30

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

単一式の暗黙的な戻り値

ここでは、ソートされた関数の2番目の引数の関数型により、クロージャーがBool値を返す必要があることが明確になります。 クロージャーの本体には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番目のString引数を参照します。

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

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]

トレーラーとしての閉鎖

関数の最後の引数をクロージャー式に渡すことは、 'Trailing Closures’を使用して宣言されます。 関数()の外側に\ {}を使用して記述されています。 関数を単一行にインラインで書き込むことができない場合に使用する必要があります。

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 および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()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

82
64
46

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

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