所谓闭包,就是一段自包含的代码块,它可以作为常量、变量使用。对于闭包,它能够捕捉和存储在定义它的上下文中任何常量和变量的引用。
全局函数、内联函数实际上就是一种特殊的闭包形式。闭包总共有三种形式:
全局函数是一种带有名字但是不捕捉任何值的闭包形式。
内联函数是一种带有名字并且捕捉来自包含它的函数内的值的闭包形式。
闭包表达式是一种不带名字、使用轻量级语法的闭包形式,能够捕捉来自包含它们上下文的值。
闭包表达式基本由闭包参数(参数名称和参数类型)、返回类型、关键字in和闭包体组成,语法形式:
{ (parameters) -> return_type in
// 闭包体
}
闭包参数可以是常量参数、变量参数和输入输出参数。不允许带默认值。可以使用变长参数,但是必须给这个变长参数命名。元祖类型也能被使用。
names.sorts({ (s1: String, s2: String) -> Bool in
return s1 > s2
})
names.sorts( { (s1: String, s2: String) -> Bool in return s1 > s2 } )
特别地,若闭包表达式作为函数参数传递给函数,那么Swift能够自动推断出闭包表达式的参数类型和返回类型,这样的话参数类型、返回箭头->以及返回类型都可以省略。
names.sort( { s1, s2 in return s1 > s2 } )
当然,绝大多数时候Swift能正确地推断出闭包表达式的参数类型和返回类型,但是,为了代码的可读性,还是建议加上参数类型和返回类型,除非闭包表达式的功能很明显。
单行闭包表达式,也就是闭包体内只包含一行代码,并且存在返回值,对于这类闭包表达式,可以省略关键字return。
names.sort( { s1, s2 in s1 > s2 } )
Swift自动提供缩写的参数名,使用$1、$2等。如果你使用缩写的参数名,并且参数类型和返回类型都能被推断出来,那么你可以省略参数列表以及关键字in。
names.sort( { $0 > $1 } )
事实上,还有一种更简短的写法,使用操作符函数。
names.sort(>)
如果你需要传递给函数最后一个参数一个闭包表达式,同时这个闭包表达式又过于长,那么可以使用尾随闭包。尾随闭包就是将闭包表达式写在函数调用的括号后面。
func someFunctionThatTakesAClosure(closure: () -> Void) {
}
someFunctionThatTakesAClosure() {
// 闭包体
}
如果函数只接受一个参数,并且你传给这个函数一个尾随闭包作为参数,那么你可以省略这个函数后面的括号"()"。
names.sort { $0 > $1 }