swift - 尾随闭包、逃逸闭包和自动闭包

  • 尾随闭包
    把闭包当做最后一个参数传入一个函数,这个闭包称之为尾随闭包。
    上代码:
// 声明一个拼接字符串的函数
// 参数就是字符串和闭包
func appendString(_ s1 : String, _ s2 : String, block closesure: (String, String) - > String) - > String) {
return closesure(s1, s2)
}

// 调用函数
appendString("hello", "kobe", block : {(s1 : String, s2 : String) -> String in s1 + s2})

打印出结果:

hello kobe

我们还可以把闭包的形参给省略:

appendString("hello", "kobe", block : {(s1 , s2 ) -> String in s1 + s2})

或者使用通配符:

appendString("hello", "kobe", block : {$0 + $1})

如果你觉得可读性不是很好,可以把闭包挪到括号外面:

appendString("hello", "kobe" ){$0 + $1}

  • 逃逸闭包
    当一个闭包作为参数传入一个函数中,但是这个闭包在函数返回后才执行,我们称这个闭包从这个函数中 逃逸
    在参数名前标记@escaping来标记闭包,表示这个闭包是可以逃逸的。
    有一个使用场景:
    如果函数内是异步执行的,但是闭包要在异步执行完了以后再执行,我们可以让这个闭包逃逸出函数再执行。
    上代码:
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}
func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}
class SomeClass { var x = 10
     func doSomething() {
         // 逃逸闭包必须显式的调用self
         someFunctionWithEscapingClosure { self.x = 100 }
         someFunctionWithNonescapingClosure { x = 200 }
     }
}
let instance = SomeClass()
 instance.doSomething() 
print(instance.x)
// 打印出 "200"
completionHandlers.first?() print(instance.x)
// 打印出 "100"

  • 自动闭包
    官方文档定义:
    自动闭包是一种自动创建的闭包,用于包装传递给函数作为参数的表达式。这种闭包不接受任何参数,当它被调用的时候,会返回被包装在其中的表达式的值。这种便利语法让你能够省略闭包的花括号,用一个普通的表达式来代替显式的闭包。

完全不知所云有木有???
其实就是当把闭包作为参数传递时,使用了@autoclosure的话,可以省略掉花括号而已!然而个人认为过度使用@autoclosure会让代码可读性变差,毕竟花括号是闭包的标准语法,省略掉以后看起来怪怪的,总之 swift就是让你能省就省。
上代码:

func test() {
   var names = ["lebron", "kobe", "sq"]
    // 注意看这里,闭包不用省略号了
 deleteNames(handler: names.remove(at: 0));
}

func deleteName(handler handler : @autoclosure ()->String) {
    print("now serving\(customerPriveder())")
}

swift真的够简洁
以上

你可能感兴趣的:(swift - 尾随闭包、逃逸闭包和自动闭包)