import Foundation
//***********************************************************************************************
//1.Closures(闭包)
//_______________________________________________________________________________________________
//介绍
//闭包是功能性自包含模块,可以在代码中被传递和使用。 Swift 中的闭包与 C 和 Objective-C 中的 blocks 以及其他一些编程语言中的 lambdas 比较相似
//闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着 这些常量和变量,俗称闭包。Swift 会为我们管理在捕获过程中涉及到的内存操作
//***********************************************************************************************
//2.Closure Expressions(闭包表达式)
//_______________________________________________________________________________________________
//使用 sorted 函数演示闭包的功能(Swift 标准库提供了 sorted 函数,会根据您提供的排序闭包将已知类型数组中的值进行排序,一旦排序完成,函数会返回一个与原数组大小相同的新数组,该数组中包含已经正确排序的 同类型元素)
let names = ["Listo", "Pin", "Melody", "Coco"]
func backwards(s1: String, s2: String) -> Bool{
return s1 > s2
}
var reversed = sorted(names, backwards) //使用函数方法排序数组
println(reversed)
reversed = sorted(names, {(s1: String, s2: String) -> Bool in return s1 > s2}) //使用标准的闭包表达式排序数组
println(reversed)
//_______________________________________________________________________________________________
//自动推断类型简化闭包
reversed = sorted(names, { s1, s2 in return s1 > s2})
println(reversed)
//_______________________________________________________________________________________________
//单行闭包可以省略 return
reversed = sorted(names, { s1, s2 in s1 > s2})
println(reversed)
//_______________________________________________________________________________________________
//闭包参数名简写
reversed = sorted(names, {$0 > $1})
println(reversed)
//_______________________________________________________________________________________________
//运算符函数应用闭包
reversed = sorted(names, >)
println(reversed)
//***********************************************************************************************
//3.Trailing Closures(Trailing 闭包)
//_______________________________________________________________________________________________
//介绍
//如果我们需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用 trailing 闭包增强代码可读性
//Trailing 闭包是一个书写在函数之外的的闭包表达式,函数支持将闭包作为最后一个参数调用
//_______________________________________________________________________________________________
//sorted 函数代码演示 Trailing 闭包
reversed = sorted(names) {$0 > $1} //可以把 {} 内的闭包表达式作为 sorted 函数的最后一个参数使用,这样写可以增强可读性
//_______________________________________________________________________________________________
//map 函数代码演示 Trailing 闭包(Swift 的 Array 类型有一个 map 方法,其获取一个闭包表达式作为其唯一参数。数组中的每一个元素调用一次该闭包函数,并返回该元素所映射的值(也可以是不同类型的值)。具体的映射方式和返回值类型由闭包来指定)
let digitNames = [0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"] //创建映射字典
let numbers = [16, 59, 676] //定义即将使用 .map 方法的数据
let strings = numbers.map{ //strings 为 numbers 数组使用闭包方法运行后返回的数组
(var number) -> String in
var output = " "
while number > 0{
output = digitNames[number % 10]! + output //digitNames 下标后跟着一个叹号 (!),因为字典下标返回一个可选值 (optional value),表明即使该 key 不存在也不会查找失败
number /= 10
}
return output
}
println(strings)
//***********************************************************************************************
//4.Capturing Values(捕获)
//_______________________________________________________________________________________________
//介绍捕获的含义
//闭包可以在其定义的上下文中捕获常量或变量。 即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值
//Swift 最简单的闭包形式是嵌套函数,也就是定义在其他函数体内的函数。嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量
//_______________________________________________________________________________________________
//代码演示嵌套函数的捕获
func makeIncrementor(forIncrement amount: Int) -> () -> Int{
var runningTotal = 0
func incrementor() -> Int{ //当我们当读看这个嵌套函数的时候会发现这个函数并没有获取任何参数,但是在函数体内部访问了 runningTotal变量和 amount 变量来实现功能
runningTotal += amount
return runningTotal
}
return incrementor
}
var incrementBySeven = makeIncrementor(forIncrement: 7)
println(incrementBySeven())
var incrementByTen = makeIncrementor(forIncrement: 10) //此时的 incrementByTen() 就是 incrementor(amount: 10) -> Int 这个函数
incrementByTen() //每次调用 incrementByTen() 就相当于每次调用一次 incrementor(amount: 10) -> Int
println(incrementByTen()) //当我每次调用 incrementor() 函数时,runningTotal 的值会返回一个新的数据依次加 10
//***********************************************************************************************
//5.Closures Are Reference Types(闭包是引用类型)
//_______________________________________________________________________________________________
//上面的例子中,incrementBySeven 和 incrementByTen 是常量,但是这些常量指向的闭包仍然可以增加其捕获的变量值。 这是因为函数和闭包都是引用类型