swiftの閉パッケージ(closure)


閉パケットは、Swiftの閉パッケージとCとObjective-Cのコードブロック(blocks)およびその他のプログラミング言語のlambdas関数は似ています.閉パケットは、上下の任意の定数と変数の使用をキャプチャおよび格納します.これは、これらの定数と変数、通称閉パケットを閉じて包むことです.Swiftは、取得中に関連するすべてのメモリ操作を管理します.関数のセクションで説明するグローバルおよびグローバルネスト関数は実際には特殊な閉パケットであり、閉パケットは以下の3つの形式の1つをとる:グローバル関数は名前があるが値を取得しない閉パケットネスト関数は名前があり、その閉関数ドメイン内の値をキャプチャできる閉パケットである
閉パケット式は、その上下の変数または定数値をキャプチャできる匿名の閉パケットである.
Swiftの閉パケット式は簡潔な格子を持ち、常
1、閉パッケージ式
(1)まず持参したsort関数を見る
Swift標準ライブラリにはsortという関数があり、指定したソートに使用する閉パッケージ関数に基づいて既知のタイプの配列の値をソートします.一旦ソートが完了すると、sort(:)方式は元の配列と同じタイプの要素を含み、要素が正しくソートされた新しい配列を返します.元の配列はsort(:)方式で変更されません.
let strs = ["ashdif", "gsdfao", "dsdokfn", "csddf"]
func compare(str1 : String, str2 : String) -> Bool {
    return str1 > str2
}
var newStrs = strs.sort(compare)
print(strs)
print(newStrs)

//["ashdif", "gsdfao", "dsdokfn", "csddf"]
//["gsdfao", "dsdokfn", "csddf", "ashdif"]

(2)閉包式構文
閉包式の構文には、次のような形式があります.
{ (parameters) -> returnType in
    statements
}

閉包式構文では、デフォルト値を指定せずに定数、変数、inoutタイプをパラメータとして使用できます.パラメータリストの最後に可変パラメータを適用することもできます.メタグループは、パラメータと戻り値としても使用できます.
let strs = ["ashdif", "gsdfao", "dsdokfn", "csddf"]
func compare(str1 : String, str2 : String) -> Bool {
    return str1 > str2
}
var newStrs = strs.sort(compare)
print(strs)
print(newStrs)

var newStrs1 = strs.sort({(str1 : String, str2 : String) -> Bool in
    return str1 < str2
})
print(newStrs1)

//["ashdif", "gsdfao", "dsdokfn", "csddf"]
//["gsdfao", "dsdokfn", "csddf", "ashdif"]
//["ashdif", "csddf", "dsdokfn", "gsdfao"]

(3)コンテキストによる型の推定
let strs = ["ashdif", "gsdfao", "dsdokfn", "csddf"]
func compare(str1 : String, str2 : String) -> Bool {
    return str1 > str2
}
var newStrs = strs.sort(compare)
print(strs)
print(newStrs)


var newStrs1 = strs.sort({(str1 : String, str2 : String) -> Bool in
    return str1 < str2
})
print(newStrs1)

var newStrs2 = strs.sort({str1, str2 in return str1 > str2})
print(newStrs2)

//["ashdif", "gsdfao", "dsdokfn", "csddf"]
//["gsdfao", "dsdokfn", "csddf", "ashdif"]
//["ashdif", "csddf", "dsdokfn", "gsdfao"]
//["gsdfao", "dsdokfn", "csddf", "ashdif"]

(4)単一式閉パッケージ暗黙的な戻り
単一式閉パッケージはreturnキーワードを非表示にすることで、単一式の結果を暗黙的に返すことができます.
var newStrs2 = strs.sort({str1, str2 in str1 > str2})

(5)パラメータ名の略語
Swift閉パッケージ式でパラメータ名の略語を使用する場合は、閉パッケージパラメータリストで定義を省略できます.また、対応するパラメータ名の略語のタイプは、関数タイプによって推定されます.inキーワードも同様に省略することができる.この場合、閉包式は完全に閉包関数体から構成されるからである.
var newStrs2 = strs.sort({ $0 > $1})

(6)演算子関数
実際には、上記の例SwiftのStringタイプは、1つの関数として2つのStringタイプのパラメータを受け入れ、Boolタイプの値を返す文字列実装を定義します.
var newStrs2 = strs.sort(>)

2、テイクアウト
閉じた式を最後のパラメータとして関数に渡す必要がある場合は、閉じたパケットに後続して関数の可読性を向上させることができます.後続の閉パケットは、関数カッコの後に書かれた閉パケット式であり、関数はそれを最後のパラメータとして適用することを支持する.
var newStrs3 = strs.sort() {$0 > $1}
let hanzi = [0 : " ", 1 : " ", 2 : " ", 3 : " ", 4 : " ", 5 : " ", 6 : " ", 7 : " ", 8 : " ", 9 : " "]
let numbers = [23342, 832, 976]
let numbersHZ = numbers.map() {
    (var number) -> String in
    var outHZ = ""
    while number > 0 {
        outHZ = hanzi[number % 10]! + outHZ
        number /= 10
    }
    return outHZ
}
print(numbers)
print(numbersHZ)

//[23342, 832, 976]
//["     ", "   ", "   "]

もう1つの簡単な例を示します.
func trailingClosure(a : Int, b : Int, c : (Int, Int) -> Bool) -> Int{
    if c(a, b) {
        return a
    }else {
        return b
    }
}

let result = trailingClosure(10, b: 13) {//    ,            ,    
    $0 > $1
}
print(result)

//13

3、取得値
閉パケットは、定義された上下これらの定数と変数を定義する元のドメインが存在しなくても、閉パケットは閉パケット関数内でこれらの値を適用し、修正することができます.Swiftの最も簡単な閉包形式はネスト関数,すなわち他の関数の関数体内に定義された関数である.ネストされた関数は、外部関数のすべてのパラメータと定義された定数と変数をキャプチャします.
//    x y  
func makecalculate(x : Int, y : Int) -> () -> Int {
    var ret = 1
    func achieve() -> Int {
        for var i = 0; i < y; i++ {  //    y
            ret *= x       //    ret   y
        }
        return ret
    }
    return achieve
}

let achiveFunc = makecalculate(3, y: 4)
print(achiveFunc())

//81

achieve関数にはパラメータはありませんが、retおよびx,y変数に関数内でアクセスします.これは,それを含む関数体内にすでに存在するretとx,y変数の応用(reference)をキャプチャすることによって実現されるからである.変数の応用を捉え,retとxを保証し,y変数はmakecalculateを適用した後も消失せず,次のachieve関数を一次的に実行する際にretが増加し続けることを保証した.
4、閉パッケージは参照タイプ
関数/閉パッケージを1つの定数に割り当てるか変数に割り当てるかは別ですが、実際には定数/変数の値を対応する関数/閉パッケージの使用に設定しています.