スウィフト閉鎖
クロージャ(クロージャ)は、使用することができますまたはコード内のパラメータ値として使用され、コードの機能自己完結型のブロックです。
CとObjective-Cのコードブロック(ブロック)と匿名関数は非常に似ているいくつかの他のプログラミング言語でスウィフトクロージャ。
グローバル関数とネストされた関数は、実際には特別なクロージャです。
フォームの閉鎖:
グローバル関数 | ネストされた関数 | 式クロージャ |
私は名前を持っていますが、任意の値をキャプチャすることはできません。 | これは、名前を持っていますが、また閉じた関数内で値をキャプチャします。 | 名も無き閉鎖、軽量の構文を使用するには、コンテキストに基づいて値をキャプチャすることができます。 |
スウィフトクロージャは、最適化の多くの場所があります。
- コンテキスト推論パラメータと戻り値の種類に応じて
- 単線式の閉鎖暗黙のリターンから(つまり、閉鎖体は、コード1行だけで、あなたはリターンを省略することができます)
- (i番目の引数ことを示す、0から···)は$ 0、$ 1とパラメータ名を、簡略化するために使用することができます
- 提供末尾の閉鎖構文(末尾の閉鎖構文)
- 既知の型の配列
- 閉鎖機能、その関数クロージャは、2つの値と同じタイプの要素の配列を渡す必要があり、2番目のパラメータの前または後ろで仕分け受信行の終了後の最初のパラメータということを示すためにブール値を返します。 最初のパラメータの値が2番目のパラメータ値の前に表示された場合は、閉鎖機能を返す必要が並べ替える
true
戻るには、逆false
。
文法
以下は、受信パラメータを定義し、クロージャの構文の指定された型を返します。
{(parameters) -> return type in statements }
例
import Cocoa let studname = { print("Swift 闭包实例。") } studname()
上記プログラム実行出力は、次のとおりです。
Swift 闭包实例。
次のクロージャフォームは2つのパラメータを取り、ブール値を返します。
{(Int, Int) -> Bool in Statement1 Statement 2 --- Statement n }
例
import Cocoa let divide = {(val1: Int, val2: Int) -> Int in return val1 / val2 } let result = divide(200, 20) print (result)
上記プログラム実行出力は、次のとおりです。
10
式クロージャ
クロージャ式は単純な構文のインラインクロージャの使用を構築するための方法です。 クロージャ式の構文、その閉鎖を構成する単純かつ明確になるように、いくつかの最適化を提供します。
ソート機能
スウィフト標準ライブラリは、ソートという名前の関数を提供し、それはあなたが提供する閉鎖機能に応じてソートするアレイ内の既知の型の値をソートするために使用されます。
ソートが完了した後、ソート(_ :)メソッドは、元と同じサイズの配列を返し、新しい配列が同じ要素の型と要素が適切にソートされている、元の配列をソート(_ :)方法を変更されていないが含まれています。
ソート(_ :)メソッドは、2つの引数を取ります。
例
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] // 使用普通函数(或内嵌函数)提供排序功能,闭包函数类型需为(String, String) -> Bool。 func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed = names.sort(backwards) print(reversed)
上記プログラム実行出力は、次のとおりです。
["S", "D", "BE", "AT", "AE"]
最初の文字列(s1が)2番目の文字列(S2)よりも大きい場合、後方関数は新しい配列をS1、S2の前に表示されることを示す、trueを返します。 文字列内の文字については、「より大きい」は「後にアルファベット順に表示されます。」という意味します これは、文字「B」は、文字「A」、「S」は、文字列「D」よりも大きい文字列よりも大きいことを意味します。 それは、「AE」の前にソートされます「AT」、アルファベット順のソートが逆になります。
パラメータ名の省略形
スウィフトは、自動的にインライン関数のパラメータ名の省略形を提供し、あなたは直接$ 1、$ 2の引数$ 0の閉鎖を介して順に呼び出すことができます。
例
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sort( { $0 > $1 } ) print(reversed)
$ 0、String型の第一および第二のパラメータの閉鎖のための$ 1です。
上記プログラム実行出力は、次のとおりです。
["S", "D", "BE", "AT", "AE"]
あなたが閉鎖式でパラメータ名の省略形を使用する場合は、クロージャパラメータリストの定義が省略されていることができ、対応するパラメータ名の頭字語タイプは関数型によって推測されます。 キーワードには省略することも可能です。
演算子関数
実際、上記の例の閉鎖式を記述するために短い方法があります。
スウィフトのString
型は、大なり記号(上の定義>
2取る関数として、文字列)の実装をString
型パラメータをと返すBool
値のタイプを。 これはと一致したsort(_:)
メソッドの第二引数の型の関数が準拠する必要があります。 したがって、あなたは、単にスウィフトが自動的に達成するための文字列関数の数よりも大きい使用することを推測することができ、大なり記号を渡すことができます。
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sort(>) print(reversed)
上記プログラム実行出力は、次のとおりです。
["S", "D", "BE", "AT", "AE"]
末尾のクロージャ
クロージャを後続することは、最後のパラメータとしてのコールをサポートするために、式、関数の閉鎖後の括弧内に記述された機能です。
func someFunctionThatTakesAClosure(closure: () -> Void) { // 函数体部分 } // 以下是不使用尾随闭包进行函数调用 someFunctionThatTakesAClosure({ // 闭包主体部分 }) // 以下是使用尾随闭包进行函数调用 someFunctionThatTakesAClosure() { // 闭包主体部分 }
例
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] //尾随闭包 var reversed = names.sort() { $0 > $1 } print(reversed)
ソート(){$ 0> $ 1}末尾の閉鎖後。
上記プログラム実行出力は、次のとおりです。
["S", "D", "BE", "AT", "AE"]
注:末尾にクロージャを使用する場合、関数一つのパラメータのみ発現閉鎖した場合、あなたも置くことができます
()
は省略。reversed = names.sort { $0 > $1 }
キャプチャ値
クロージャはその定義のコンテキストに定数または変数捕捉することができます。
元のドメインのこれらの定数や変数のさえ定義が存在しない、閉鎖はまだこれらの値の生体内閉鎖参照および変更で機能することができます。
閉鎖のスウィフト最も簡単な形は、ネストされた関数であり、関数は、関数の他の機能の本体で定義されています。
ネストされた関数は、その外部関数のパラメータと定義された定数と変数のすべてをキャプチャすることができます。
この例を見てみましょう。
func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor }
関数makeIncrementorは、それがInt型のamoutをのパラメータを持っており、それが外部パラメータ名forIncremetを持って、あなたが呼び出すとき、あなたは外部名を使用しなければならないことを意味します。 戻り値は()-> Int
関数。
タイトル機能では、変数と関数の積算合計のインクリメンタを宣言します。
インクリメンタ関数は引数を得ることはありませんが、関数の本体に積算合計と量変数にアクセスします。 それは、その既存の積算合計と実現可変量をキャプチャすることにより、関数の本体が含まれているためです。
何も変更量変数が存在しないので、インクリメンタは、実際にキャプチャして、インクリメンタなどのコピーと一緒に格納された変数のコピーを格納します。
私たちは、この関数を呼び出すときに蓄積されます:
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 print(incrementByTen()) // 返回的值为20 print(incrementByTen()) // 返回的值为30 print(incrementByTen())
上記プログラム実行出力は、次のとおりです。
10 20 30
クロージャは参照型であります
上記の例では、incrementByTenは一定であるが、これらの定数の閉鎖点はまだ変数捕捉の値を増加させることができます。
機能及びクロージャーが参照型であるためです。
あなたは定数または変数に割り当てられた機能/閉鎖されているかどうかは、あなたが実際に定数/変数対応する機能/閉鎖参照の値を設定しています。 上記の例では、incrementByTen基準点はむしろ閉鎖自体の含有量よりも、一定であるクロージャ。
これはまた、2つの異なる定数/変数の閉鎖を割り当てた場合、両方の値が同じ閉鎖を指すようになりますことを意味します。
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 incrementByTen() // 返回的值为20 incrementByTen() // 返回的值为30 incrementByTen() // 返回的值为40 incrementByTen() let alsoIncrementByTen = incrementByTen // 返回的值也为50 print(alsoIncrementByTen())
上記プログラム実行出力は、次のとおりです。
50