根据Swift的闭包文档所述:
Swift的闭包表达式具有干净、清晰的风格,优化可以在常见情况下鼓励简洁、无杂乱语法的写法。这些优化包括:
- 从上下文中推断参数和返回值类型
- 单表达式闭包的隐式返回
- 简写参数名称
- 尾随闭包语法
那么什么是Swift闭包的“尾随闭包语法”?
根据Swift的闭包文档所述:
Swift的闭包表达式具有干净、清晰的风格,优化可以在常见情况下鼓励简洁、无杂乱语法的写法。这些优化包括:
- 从上下文中推断参数和返回值类型
- 单表达式闭包的隐式返回
- 简写参数名称
- 尾随闭包语法
那么什么是Swift闭包的“尾随闭包语法”?
尾随闭包是写在函数调用的括号后面,即使它仍然是函数的一个参数。当您使用尾随闭包语法时,不需要将闭包的参数标签作为函数调用的一部分进行编写。
func doSomething(number:Int, onSuccess closure:(Int)->Void) {
closure(number * number * number)
}
doSomething(number: 100) { (numberCube) in
print(numberCube) // prints 1000000
}
该函数调用中缺少onSuccess参数标签。虽然闭包已在函数参数列表中包含,但Swift会将其从参数块中移除以使代码更易读。
- 一个闭包表达式,它被写在支持它的函数调用的括号外面(并且在括号之后)
这只是为了写得更简洁、更易读而存在的语法糖。
给你一个使用案例:
你有一个需要另一个函数(或闭包)作为参数的函数,像这样:
func fooFunc(paramfunc: () -> Void) {
paramfunc();
}
调用函数并将函数作为参数传递是很常见的。如果给它一个闭包,意味着你所传递的参数是一个匿名函数,它被写在一对大括号{}
中,并在开头有类型签名(它是一个匿名函数)。
当调用需要函数作为参数的函数时,在括号后面写闭包或省略括号(如果它是唯一的参数)(在Swift 5.3中支持多个尾随闭包)就可以使用尾随闭包语法。
fooFunc { () -> Void in
print("Bar");
}
fooFunc() { () -> Void in
print("Bar");
}
函数名后面的括号甚至可以省略。
func funcWithATrailingClosure(closure: () -> Void) {
// function body goes here
}
// Here's how you call this function without using a trailing closure:
funcWithATrailingClosure(closure: {
// closure's body goes here
})
// Here's how you call this function with a trailing closure instead:
funcWithATrailingClosure() {
// trailing closure's body goes here
}
()
can also be omitted. someFunctionThatTakesAClosure { }
- Leo Dabusclass Object {
func foo(bar: String, baz: (() -> Void)) { }
}
您可以像正常调用一样使用它:
let obj = Object()
obj.foo(bar: "", baz: { foo() })
或者像这样的尾随
obj.foo(bar: "") { foo() }
另外,如果存在多个类似这样的尾随闭包:
func foo(bar: String, baz: (() -> Void), pippo: ((IndexPath) -> Void)) { }
然后如果你尝试像这样调用它:
obj.foo(bar: "") { _ in
} pippo: { _ in
}
出现以下错误:
上下文类型的闭包参数列表需要1个参数,不能隐式忽略
为了避免这个错误,你需要这样调用:
obj.foo(bar: "") {
} pippo: { _ in
}
最后,如果你想使用像Int这样的另一种闭包类型
func foo(bar: String, baz: ((Int) -> Void), pippo: ((IndexPath) -> Void)) { }
然后像这样调用:
obj.foo(bar: "") { _ in //baz
} pippo: { _ in
}
如果你需要将一个闭包表达式作为函数的最后一个参数传递给函数,并且闭包表达式很长,那么将其编写为尾随闭包可能会很有用。尾随闭包写在函数调用的括号之后,即使它仍然是函数的参数。当你使用尾随闭包语法时,不需要在函数调用中写出闭包的参数标签。
func someFunctionThatTakesAClosure(closure: () -> Void) {
// function body goes here
}
// Here's how you call this function without using a trailing closure:
someFunctionThatTakesAClosure(closure: {
// closure's body goes here
})
// Here's how you call this function with a trailing closure instead:
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}
reversedNames = names.sorted { $0 > $1 }
()
can also be omitted. someFunctionThatTakesAClosure { }
- Leo Dabus