http://blog.csdn.net/huangchentao/article/details/32714185

闭包 Closures

1.闭包表达式

闭包表达式是一种利用简单语法构建内联包的方式,提供一些语法优化,使得闭包代码变得更加简单明了

1.1sort函数

Swift标准库提供了sort函数,将已知类型数组中的值进行排序,返回一个与原数组大小相等但元素已正确排序的数组
sort函数需要传入两个参数:
 1.已知类型的数组
 2.传入两个跟数组相同类型参数的闭包函数,并返回一个布尔值告诉sort函数排序结束后传入的第一个参数排在第二个参数的前面还是后面,如果第一个参数值出现在第二个参数值前面,排序闭包函数需要返回true,否则返回false

  1. let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

该例子对String类型的数组进行排序,因此该排序闭包函数类型为 (String, String) -> Bool
提供排序闭包函数的另一种方式是写一个符合其类型要求的普通函数,并将其作为sort函数的第二个参数传入

  1. func backwards(s1: String, s2: String) -> Bool {
  2. return s1 > s2
  3. }
  4. var reversed = sort(names, backwards)
  5. // reversed is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

1.2闭包表达式语法

闭包表达式一般形式,可以使用常量、变量和inout类型作为参数,不提供默认值,也可以在参数列表后面使用可变参数。元组也可以作为参数和返回值

  1. { (parameters) -> return type in
  2. statements
  3. }
  4. // backwards函数对应的闭包表达式版本,闭包的函数体部分由关键字 in 引入
  5. // 该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体开始
  6. reversed = sort(names, { (s1: String, s2: String) -> Bool in
  7. return s1 > s2
  8. })
  9. // 简写形式
  10. reversed = sort(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )

1.3根据上下文推断类型

因为排序闭包函数是作为sort函数的参数进行传入,Swift可以判断其参数和返回值的类型

  1. reversed = sort(names, { s1, s2 in return s1 > s2 } )

1.4单行表达式闭包隐式返回

单行表达式闭包可以通过隐藏return关键字来隐式返回单行表达式的结果

  1. reversed = sort(names, { s1, s2 in s1 > s2 } )

1.5参数名称缩写

Swift自动为内联函数提供了参数名称缩写功能,可直接通过 $0,$1,$2 来顺序调用闭包的参数。如果您在闭包表达式中使用参数名称缩写,可以在闭包参数列表中省略对其的定义,并且对应参数名称缩写的类型会通过函数类型进行推断。 in关键字也同样可以被省略,因为此时闭包表达式完全由闭包函数体构成

  1. reversed = sort(names, { $0 > $1 } )

1.6运算符函数

Swift 的String类型定义了关于大于号 (>) 的字符串实现,其作为一个函数接受两个String类型的参数并返回Bool类型的值。 而这正好与sort函数的第二个参数需要的函数类型相符合。 因此可以简单地传递一个大于号,Swift可以自动推断出您想使用大于号的字符串函数实现

  1. reversed = sort(names, >)

2.尾随闭包

如果需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。如果函数只需要闭包表达式一个参数,当使用尾随闭包时,甚至可以把()省略掉。

  1. func someFunctionThatTakesAClosure(closure: () -> ()) {
  2. // function body goes here
  3. }
  4. // 以下是不使用尾随闭包进行函数调用
  5. someFunctionThatTakesAClosure({
  6. // closure's body goes here
  7. })
  8. //  以下是使用尾随闭包进行函数调用
  9. someFunctionThatTakesAClosure() {
  10. // trailing closure's body goes here
  11. }
  12. //在上例中作为sort函数参数的字符串排序闭包可以改写为:
  13. reversed = sort(names) { $0 > $1 }
  14. let digitNames = [
  15. 0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
  16. 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
  17. ]
  18. let numbers = [16, 58, 510]
  19. let strings = numbers.map {
  20. (var number) -> String in
  21. var output = ""
  22. while number > 0 {
  23. output = digitNames[number % 10]! + output
  24. number /= 10
  25. }
  26. return output
  27. }
  28. // strings is inferred to be of type String[]
  29. // its value is ["OneSix", "FiveEight", "FiveOneZero"]

3.值捕获

闭包可以在其定义的上下文中捕获常量或变量。即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。Swift最简单的闭包形式是嵌套函数,也就是定义在其他函数的函数体内的函数。 嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量。

  1. func makeIncrementor(forIncrement amount: Int) -> () -> Int {
  2. var runningTotal = 0
  3. func incrementor() -> Int {
  4. runningTotal += amount
  5. return runningTotal
  6. }
  7. return incrementor
  8. }
  9. func incrementor() -> Int {
  10. runningTotal += amount
  11. return runningTotal
  12. }
  13. let incrementByTen = makeIncrementor(forIncrement: 10)
  14. incrementByTen()
  15. // returns a value of 10
  16. incrementByTen()
  17. // returns a value of 20
  18. incrementByTen()
  19. // returns a value of 30
  20. let incrementBySeven = makeIncrementor(forIncrement: 7)
  21. incrementBySeven()
  22. // returns a value of 7
  23. incrementByTen()
  24. // returns a value of 40

4.闭包是引用类型

无论将函数/闭包赋值给一个常量还是变量,实际都是将常量/变量的值设置为对应函数/闭包的引用,如果将闭包赋给了两个不同的常量/变量,两个值都会指向同一个闭包

  1. let alsoIncrementByTen = incrementByTen
  2. alsoIncrementByTen()
  3. // returns a value of 50

版权声明:本文为博主原创文章,未经博主允许不得转载。

Swift 闭包(六)的更多相关文章

  1. Swift闭包概念与常见使用场景总结

    ·Swift 闭包 闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值. Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些 ...

  2. Swift --闭包表达式与闭包(汇编分析)

    在Swift中,可以通过func定义一个函数,也可以通过闭包表达式定义一个函数! 一.闭包表达式 概念 闭包表达式与定义函数的语法相对比,有区别如下: 去除了func 去除函数名 返回值类型添加了关键 ...

  3. swif(六)swift闭包

    // // main.swift // LessonSwiftSix // // Created by keyan on 15/9/13. // Copyright (c) 2015年 keyan. ...

  4. swift 闭包循环引用

    当使用闭包时,类本身持有self,然后又在闭包中访问了self或者self的属性,就会导致恶心额循环引用.swift提供的解决方法是在闭包中定义捕获列表,捕获列表是闭包想怎么引用捕获来的变量.例如下面 ...

  5. swift 闭包

    闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 这就是所谓的闭合并包裹着 这些常量和变量,俗称闭包. Swift标准库中提供了sort排序函数,sort函数的第二个参数是个闭包.和OC中的bl ...

  6. [ios][swift]使用swift闭包进行viewcontroller反向传值

    闭包参考:http://c.biancheng.net/cpp/html/2285.html   闭包详解 传值参考:http://www.tuicool.com/articles/vy2uUz Sw ...

  7. swift 闭包简写实际参数名$0、$1等理解

    Swift 自动对行内闭包提供简写实际参数名,你也可以通过 $0 , $1 , $2 等名字来引用闭包的实际参数值. 如果你在闭包表达式中使用这些简写实际参数名,那么你可以在闭包的实际参数列表中忽略对 ...

  8. Swift闭包(Closure)

    语法: { (parameters) ->return type in statements} 实例:采用函数实现: let names =["Chris", "A ...

  9. swift闭包传值

    不知道原理,就知道这么用的,皮毛上的那一点. 寻思着把以前的项目改成swift的,结果了,,, 反向传值 一. //类似于OC中的typedef typealias sendValueClosure= ...

随机推荐

  1. C++学习013多态

    何为多态 面向对象最要的特征之一就是多态,而纯虚函数是实现多态的主要方式.它可以提供一个通过用的接口,同样调用一个方法, 由于运算对象不同,方法也不同,这也就是所谓的动态绑定. #include &l ...

  2. 自动化测试--封装getDriver的方法

    在自动化测试的时候,通常都会把最常用的功能封装起来,实现通用性. 该篇博客是实现了getDriver方法的封装. 第一次封装的时候,是使用的传参. @Parameters(value = {" ...

  3. [转]juery-zTree的基本用法

    [简介] zTree 是利用 jQuery 的核心代码,实现一套能完成大部分常用功能的 Tree 插件 兼容 IE.FireFox.Chrome 等浏览器 在一个页面内可同时生成多个 Tree 实例 ...

  4. VS2010历史记录清理

    把如下粘贴到文本文件里,另存为批处理文件.(后缀为 *.bat)双击执行就可 @echo off cd \ @echo on @REG Delete HKEY_CURRENT_USER\Softwar ...

  5. C - 最长公共子序列

    C - 最长公共子序列 Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others) Problem De ...

  6. 搭建Elasticsearch 5.4分布式集群

    多机集群中的节点可以分为master nodes和data nodes,在配置文件中使用Zen发现(Zen discovery)机制来管理不同节点.Zen发现是ES自带的默认发现机制,使用多播发现其它 ...

  7. 用户代理UA

    简介: 用户代理英文全称为User Agent,简称UA,现在被广泛用来标识浏览器客户端信息. 发展状况: User Agent在互联网早期就已经存在,那时互联网是完全基于文本的,用户直接浏览器互联网 ...

  8. [剑指Offer] 19.顺时针打印矩阵

    [思路]本题关键在于 右->左 和 下->上 两个循环体中的判断条件,即判断是否重复打印. class Solution { public: vector<int> print ...

  9. BZOJ4345 POI2016Korale(构造+堆+线段树)

    注意到k与n同阶,考虑构造一种枚举子集的方式,使得尽量先枚举较小的子集.首先sort一下,用堆维护待选子集.每次取出最小子集,并加入:1.将子集中最大数ai替换为ai+1 2.直接向子集中添加ai+1 ...

  10. Codeforces Round #390 (Div. 2) E(bitset优化)

    题意就是一个给出2个字符矩阵,然后进行匹配,输出每个位置的匹配的结果 (超出的部分循环处理) 一种做法是使用fft,比较难写,所以没有写 这里使用一个暴力的做法,考虑到一共只出现26个字符 所以使用一 ...