Swift4 基礎(chǔ)部分:Closures

本文是學(xué)習(xí)《The Swift Programming Language》整理的相關(guān)隨筆,基本的語法不作介紹,主要介紹Swift中的一些特性或者與OC差異點(diǎn)。

系列文章:

Closures

閉包表達(dá)式語法(Closure Expression Syntax)

Closure expression syntax has the following general form:

 { (parameters) -> return type in
    statements
}

例子:數(shù)組排序的例子

var names:[String] = ["B","A","C"];
names = names.sorted(by: {
    (num1:String,num2:String) -> Bool in
    return num1 < num2;
});
print(names);

執(zhí)行結(jié)果:

["A", "B", "C"]

上下文檢測(cè)類型(Inferring Type From Context)

Because the sorting closure is passed as an argument to a 
method, Swift can infer the types of its parameters and 
the type of the value it returns. The sorted(by:) method 
is being called on an array of strings, so its argument 
must be a function of type (String, String) -> Bool. This 
means that the (String, String) and Bool types do not need 
to be written as part of the closure expression’s 
definition.
  • 排序的閉包因?yàn)镾wift中的類型檢測(cè)機(jī)制,所以可以省掉寫入String,-> Bool

針對(duì)上述的例子做簡(jiǎn)化:

var names:[String] = ["B","A","C"];
names = names.sorted(by: {
    (name1,name2) in
    return name1 < name2;
});
print(names);

單表達(dá)式閉包的隱式返回(Implicit Returns from Single-Expression Closures)

Single-expression closures can implicitly return the 
result of their single expression by omitting the return 
keyword from their declaration
  • 單表達(dá)式的閉包可以省略掉return關(guān)鍵字

繼續(xù)簡(jiǎn)化上述例子:

var names:[String] = ["B","A","C"];
names = names.sorted(by: {
    (name1,name2) in name1 < name2;
});
print(names);

參數(shù)名稱縮寫(Shorthand Argument Names)

Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.
  • 結(jié)合閉包中類型的檢測(cè),閉包中的參數(shù)名可以使用$0, $1, $2代替

繼續(xù)簡(jiǎn)化上述例子:

var names:[String] = ["B","A","C"];
names = names.sorted(by: {
    $0 < $1;
});
print(names);

操作方法(Operator Methods)

There’s actually an even shorter way to write the closure 
expression above. Swift’s String type defines its string-
specific implementation of the greater-than operator (>) 
as a method that has two parameters of type String, and 
returns a value of type Bool.
  • 繼續(xù)簡(jiǎn)化可以直接用>,<表示比較結(jié)果

繼續(xù)簡(jiǎn)化例子:

var names:[String] = ["B","A","C"];
names = names.sorted(by:<);
print(names);

尾隨閉包(Trailing Closures)

If you need to pass a closure expression to a function as 
the function’s final argument and the closure expression 
is long, it can be useful to write it as a trailing 
closure instead. A trailing closure is written after the 
function call’s parentheses, even though it is still an 
argument to the function. When you use the trailing 
closure syntax, you don’t write the argument label for the 
closure as part of the function call.
  • 當(dāng)閉包是函數(shù)中的最后一個(gè)參數(shù)時(shí),函數(shù)調(diào)用可以省略掉參數(shù)標(biāo)簽的寫法,簡(jiǎn)化函數(shù)

閉包是引用類型數(shù)據(jù)(Closures Are Reference Types)

In the example above, incrementBySeven and incrementByTen 
are constants, but the closures these constants refer to 
are still able to increment the runningTotal variables 
that they have captured. This is because functions and 
closures are reference types.
  • Swift中的閉包是引用類型的數(shù)據(jù)

例子:

var num = 0;
func increment(completion:() -> Void){
    completion();
    print("num:\(num)");
}
increment {
    num += 10;
}
let referIncrement = increment;
referIncrement{
    num += 20;
}

執(zhí)行結(jié)果:

num:10
num:30

逃逸閉包(Escaping Closures)

A closure is said to escape a function when the closure is 
passed as an argument to the function, but is called after 
the function returns. When you declare a function that 
takes a closure as one of its parameters, you can write 
@escaping before the parameter’s type to indicate that the 
closure is allowed to escape.
  • Swift中如果需要逃逸閉包需要利用關(guān)鍵字@escaping修飾

例子:

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

class SomeClass {
    var x = 10
    func doSomething() {
        
        someFunctionWithEscapingClosure(completionHandler: {
            self.x = 100;
        });
        
        someFunctionWithNonescapingClosure(closure: {
            x = 200;
        });
        
        // 以下的調(diào)用方式一樣可行,同時(shí)說明了尾隨閉包的使用
        //someFunctionWithEscapingClosure { self.x = 100 }
        //someFunctionWithNonescapingClosure { x = 200 }
    }
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)
completionHandlers.first?()
print(instance.x)

執(zhí)行結(jié)果:

200
100

自動(dòng)閉包(Autoclosures)

An autoclosure is a closure that is automatically created 
to wrap an expression that’s being passed as an argument 
to a function. It doesn’t take any arguments, and when 
it’s called, it returns the value of the expression that’s 
wrapped inside of it.
  • Swift中的自動(dòng)閉包能動(dòng)態(tài)的封裝一個(gè)表達(dá)式為一個(gè)函數(shù)的參數(shù),自動(dòng)閉包不能帶任何的參數(shù)

例子:


var num = 1;
func filter(contions:() -> Bool){
    if contions(){
        num += 3;
        print("num:\(num)");
    }else{
        num += 1;
        print("num:\(num)");
        filter(contions: {num % 3 == 0})
    }
}
filter(contions: { num % 3 == 0 })

執(zhí)行結(jié)果:

num:2
num:3
num:6

下面開始利用@autoclosure簡(jiǎn)化:

var num = 1;
func filter(_ contions: @autoclosure () -> Bool){
    if contions(){
        num += 3;
        print("num:\(num)");
    }else{
        num += 1;
        print("num:\(num)");
        filter(num % 3 == 0)
    }
}
filter(num % 3 == 0)
Overusing autoclosures can make your code hard to 
understand. The context and function name should make it 
clear that evaluation is being deferred.
  • autoclosure的過度使用并不好,會(huì)讓代碼邏輯看起來更難理解,必須了解上下文中函數(shù)的定義才可結(jié)合使用
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容