1. * 闭包(Closures)
  2. * 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。
  3. * 在Swift中的闭包与C、OC中的blocks和其它编程语言(如Python)中的lambdas类似。
  4. * 闭包可以捕获和存储上下文中定义的的任何常量和变量的引用。这就是所谓的变量和变量的自封闭,
  5. * 因此命名为”闭包“("Closures)").Swift还会处理所有捕获的引用的内存管理。
  6. *
  7. * 全局函数和嵌套函数其实就是特殊的闭包。
  8. * 闭包的形式有:
  9. * (1)全局函数都是闭包,有名字但不能捕获任何值。
  10. * (2)嵌套函数都是闭包,且有名字,也能捕获封闭函数内的值。
  11. * (3)闭包表达式都是无名闭包,使用轻量级语法,可以根据上下文环境捕获值。
  12. *
  13. * Swift中的闭包有很多优化的地方:
  14. * (1)根据上下文推断参数和返回值类型
  15. * (2)从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
  16. * (3)可以使用简化参数名,如$0, $1(从0开始,表示第i个参数...)
  17. * (4)提供了尾随闭包语法(Trailing closure syntax)
  18. */
  19. // 下面用Swift标准库中的sort方法来一步步简化闭包写法
  20. // sort函数需要两个参数
  21. // 参数一:数组
  22. // 参数二:一个闭包:带有两个参数,这两个参数类型与数组中的元素类型相同,返回值是Bool
  23. var names = ["Swift", "Arial", "Soga", "Donary"]
  24. // 第一种方式:使用函数
  25. func backwards(firstString: String, secondString: String) -> Bool {
  26. return firstString > secondString // 升序排序
  27. }
  28. // 这里第二个参数,传了一个函数
  29. // reversed is equal to ["Swift", "Soga", "Donary", "Arial"]
  30. var reversed = sort(nams, backwards)
  31. // 第二种方式:使用闭包方式
  32. // 完整闭包写法是在花括号内有参数列表和返回值,用关键字in表明闭包体的开始
  33. // (firstString: String, secondString: String) 闭包参数列表
  34. // -> Bool 指明闭包返回值类型是Bool
  35. // in关键字表明闭包体的开始
  36. reversed = sort(names, { (firstString: String, secondString: String) -> Bool in
  37. return firstString > secondString
  38. })
  39. // 这里可以进一步简化写法,因为闭包代码比较短,可以写到一行上
  40. reversed = sort(names, { (firstString: String, secondString: String) -> Bool in return firstString > secondString})
  41. // 下面再进一步简化写法 :根据环境上下文自动推断出类型
  42. // 参数列表都没有指明类型,也没有指明返回值类型,这是因为swift可以根据上下文推测出
  43. // firstString和secondString的类型会是names数组元素的类型,而返回值类型会根据return语句结果得到
  44. reversed = sort(names, { firstString, secondString in return firstString > secondString})
  45. // 再进一步简化:隐式返回(单行语句闭包)
  46. // 因为闭包体只有一行代码,可以省略return
  47. reversed = sort(names, { firstString, secondString in firstString > secondString})
  48. // 再进一步简化:使用简化参数名($i,i=0,1,2...从0开始的)
  49. // Swift会推断出闭包需要两个参数,类型与names数组元素相同
  50. reversed = sort(names, { $0 > $1 })
  51. // 最简单的一种写法:使用操作符
  52. reversed = sort(names, >)
  53. /*
  54. * 尾随闭包(Trailing Closures)
  55. * 如果函数需要一个闭包参数作为参数,且这个参数是最后一个参数,而这个闭包表达式又很长时,
  56. * 使用尾随闭包是很有用的。尾随闭包可以放在函数参数列表外,也就是括号外。如果函数只有一个参数,
  57. * 那么可以把括号()省略掉,后面直接跟着闭包。
  58. */
  59. // Array的方法map()就需要一个闭包作为参数
  60. let strings = numbers.map { // map函数后面的()可以省略掉
  61. (var number) -> String in
  62. var output = ""
  63. while number > 0 {
  64. output = String(number % 10) + output
  65. number /= 10
  66. }
  67. return output
  68. }
  69. /* 捕获值
  70. * 闭包可以根据环境上下文捕获到定义的常量和变量。闭包可以引用和修改这些捕获到的常量和变量,
  71. * 就算在原来的范围内定义为常量或者变量已经不再存在(很牛逼)。
  72. * 在Swift中闭包的最简单形式是嵌套函数。
  73. */
  74. func increment(#amount: Int) -> (() -> Int) {
  75. var total = 0
  76. func incrementAmount() -> Int {
  77. total += amount // total是外部函数体内的变量,这里是可以捕获到的
  78. return total
  79. }
  80. return incrementAmount // 返回的是一个嵌套函数(闭包)
  81. }
  82. // 闭包是引用类型,所以incrementByTen声明为常量也可以修改total
  83. let incrementByTen = increment(amount: 10)
  84. incrementByTen() // return 10,incrementByTen是一个闭包
  85. // 这里是没有改变对increment的引用,所以会保存之前的值
  86. incrementByTen() // return 20
  87. incrementByTen() // return 30
  88. let incrementByOne = increment(amount: 1)
  89. incrementByOne() // return 1
  90. incrementByOne() // return 2
  91. incrementByTen() // return 40
  92. incrementByOne() // return 3

最新文章

  1. 怎么写makefile?(转)
  2. 关于vue.js中列表渲染练习
  3. PHP学习计划
  4. PHP中的替代语法(冒号、endif、endwhile、endfor)
  5. 软件工程 speedsnail 第二次冲刺1次
  6. hihocoder 1038 01背包
  7. opencv拼接相关1
  8. OSGI学习总结
  9. 【HighCharts系列教程】三、图表属性——chart
  10. 201521123095 《Java程序设计》第1周学习总结
  11. Navicat for Mysql 暴力破解教程
  12. Swift快速给Cocoa库内置类添加便捷初始化器
  13. 业务配置开发平台qMISPlat 2.0 产品介绍
  14. c/c++ 重载运算符 关系,下标,递增减,成员访问的重载
  15. Android-垂直滑动的ViewPager
  16. mysql+centos7+主从复制
  17. CMake的一些正确姿势
  18. Python_collections_OrderedDict有序字典部分功能介绍
  19. shell参数扩展
  20. 面试官提出的问题应该怎么答?(如开发中使用过EasyUI吗?)

热门文章

  1. Hot-Bar 軟板設計注意事項
  2. Kruskal-Wallis Test and Friedman test
  3. window快捷登陆linux的的设置方式(设置ssh的config配置)
  4. 学习Java这几个快捷键你得知道(不断更新中)
  5. html系列教程--文本格式化
  6. How to Send an Email Using UTL_SMTP with Authenticated Mail Server. (文档 ID 885522.1)
  7. Oracle EBS 如何月结[Z]
  8. Java Tomcat Glassfish Weblogic远程debug(remote debug)
  9. 关于智能指针auto_ptr
  10. mysql 按日期查询