4.Swift Syntax Basics (函数和闭包)
函数都明白,但是闭包是什么?其实就是匿名函数。
闭包实际上指的是一块封闭的作用域,里面有一串代码,外面影响不到里面。
而函数是闭包的一种形态,就是有名字的闭包。如果不给名字,就是匿名函数,匿名的闭包。通常同时说函数和闭包时,应该是在说一般函数和匿名函数。
在 Swift 中,闭包是头等类型的(first-class),可以作为参数接收,也可以作为返回值返回。
声明一个函数或匿名函数的时候需要定义参数和返回值,参数写在括号中,用 ->
于返回值分隔开。匿名闭包作为回调函数时,由于类型是已知的,可以省略不写。
另外不同于 JavaScript 的箭头函数和 Java 的 Lambda 表达式,Swift 中的匿名闭包包括参数返回值定义都是写在大括号里面的,参数返回值定义和代码体之间用 in
关键字来分隔。
函数可以使用元组返回多个返回值。
函数和闭包
使用 func
关键字声明一个函数。使用 ->
区分函数参数和返回值类型。
func greet(person: String, day: String) -> String { |
默认情况下,函数使用参数名作为参数的标签。你可以在参数名的前面自定义标签,或者用 _
表示不使用标签。
func greet(_ person: String, on day: String) -> String { |
使用元组来组合值,可以用来让函数返回多个值。元组的元素可以通过名称或者索引访问。
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) { |
R:元组(Tuple)的概念应该是来自 Python。通过索引访问元素时是 0 基的。
函数可以嵌套。嵌套函数可以访问外面一层函数定义的变量。你可以用嵌套函数来组织一个很长的,或者很复杂的函数。
func returnFifteen() -> Int { |
函数是头等类型的(first-class)。函数可以返回一个函数作为其返回值。
func makeIncrementer() -> ((Int) -> Int) { |
函数也可以将另一个函数作为一个参数获取。
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool { |
R:支持头等函数(first-class functions)的语言可以将函数作为一个对象进行传递。动态语言中 JavaScript 和 Python 等支持,静态语言中 Golang 和 Swift 等支持,Java 不支持。
R:然后开始讲闭包。
函数实际上是闭包的一种情况:一块代码可以在之后被执行。闭包中的代码可以访问创建闭包的作用域下可用的变量和函数,即使当你真正执行它的时候是在另一个作用域中。你已经看到了,嵌套函数就是这样的。可以创建一个匿名的闭包,使用大括号包围一块代码,用 in
关键字分隔参数返回值定义和代码体。
numbers.map({ (number: Int) -> Int in |
R:闭包一般指的是匿名函数呀。函数是有名字的闭包。
闭包可以写的更简单。如果闭包的类型是已知的,这种情况一般是指派回调函数时,你可以省略参数定义,或者返回值定义,或者全都省略。单语句的闭包隐式的将语句的结果作为返回值返回。
let mappedNumbers = numbers.map({ number in 3 * number }) |
R:JavaScript 和 Python 中常见的匿名函数写法。
你可以不使用变量名,使用数字来获取变量。在写简短的闭包时会非常有用。当闭包作为函数的最后一个参数时可以将闭包放在括号的外面,如果这个函数仅接收一个闭包作为参数,你甚至可以把括号都省了。
let sortedNumbers = numbers.sorted { $0 > $1 } |