我给Swift 中的闭包一个定义:闭包是自包含的匿名函数代码块,可以作为表达式、函数参数和函数返回值,闭包表达式的运算结果是一种函数类型。

Swift中的闭包类似于Objective-C中的代码块、Java中的匿名内部类。

使用闭包表达式

Swift中的闭包表达式很灵活,其标准语法格式如下:

{ (参数列表) ->返回值类型 in

语句组

}

其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是后面有in关键字。

Swift提供了多种闭包简化写法,我来介绍下面几种不同形式:

1、类型推断简化

类型推断是Swift的强项,Swift可以根据上下文环境推断出参数类型和返回值类型。以下代码是标准形式的闭包:

{(a:Int, b:Int) -> Intin

return a + b

}

Swift能推断出参数a和b是Int类型,返回值也是Int类型。简化形式如下:

{(a, b) in return a + b }

{a, b in return a + b }  //参数列表括号也可以省略

2、隐藏return关键字

在闭包内部语句组只有一条语句,如return a + b等,那么这种语句都是返回语句。前面的关键字return可以省略,省略形式如下:

{a, b in a + b }

使用这种简化方式修改后的示例代码如下:

  1. func calculate(opr :String)-> (Int,Int)-> Int {
  2. var result : (Int,Int)-> Int
  3. switch (opr) {
  4. case "+" :
  5. result = {a, b in a + b } //return关键字省略了
  6. default:
  7. result = {a, b in a - b } //return关键字省略了
  8. }
  9. return result
  10. }

省略的前提是闭包中只有一条return语句。

3、省略参数名称

Swift提供了参数名省略功能,我们可以用$0、$1、$2…来指定闭包中参数,$0指代第一个参数,$1指代第二个参数,$2指代第三个参数,以此类推$n+1指代第n个参数。

使用参数名省略功能,在闭包中必须省略参数列表定义,Swift能够推断出这些缩写参数的类型。参数列表省略了,in关键字也需要省略。参数名省略之后如下所示:

{$0 + $1}

使用参数名省略后的示例代码如下:

  1. func calculate(opr :String)-> (Int,Int)-> Int {
  2. var result : (Int,Int)-> Int
  3. switch (opr) {
  4. case "+" :
  5. result = {$0 + $1} //采用了参数名省略
  6. default:
  7. result = {$0 - $1} //采用了参数名省略
  8. }
  9. return result
  10. }
  11. let f1:(Int,Int)-> Int = calculate("+")
  12. print("10 + 5 = \(f1(10,5))")
  13. let f2:(Int,Int)-> Int = calculate("-")
  14. print("10 - 5 = \(f2(10,5))")

4、使用闭包返回值

闭包表达本质上是函数类型,是有返回值的,我们可以直接在表达式中使用闭包的返回值。重新修改add和sub闭包,示例代码如下:

  1. let c1:Int = {(a:Int, b:Int) -> Int in
  2. return a + b
  3. }(10,5)
  4. print("10 + 5 = \(c1)")

解释:给c1赋值,后面是一个闭包表达式。但是闭包表达式不能直接赋值给c1,因为c1是Int类型,需要闭包的返回值。这就需要在闭包结尾的大括号后面接一对小括号(10,5),通过小括号(10,5)为闭包传递参数。

闭包表达式可以作为函数的参数传递,如果闭包表达式很长,就会影响程序的可读性。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。

下面我们来看一个示例代码:

  1. func calculate(opr: String, funN:(Int, Int) -> Int) { 
  2. //最后一个参数funN是(Int,Int)-> Int函数类型,funN可以接收闭包表达式
  3. switch (opr) {
  4. case "+" :
  5. print("10 + 5 = \(funN(10,5))")
  6. default:
  7. print("10 - 5 = \(funN(10,5))")
  8. }
  9. }
  10. calculate("+", funN: {(a: Int, b: Int) -> Int in return a + b })  //调用
  11. calculate("+"){(a: Int, b: Int) -> Int in return a + b } //调用,这种形式就是尾随闭包
  12. calculate("+") { $0 + $1 }  //调用,这种形式就是尾随闭包

需要注意的是,闭包必须是参数列表的最后一个参数,如果calculate函数采用如下形式定义:

func calculate(funN:(Int, Int) ->Int, opr:String) {

...

}

由于闭包表达式不是最后一个参数,那么调用calculate函数就不能使用尾随闭包写法的。

swift闭包-备的更多相关文章

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

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

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

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

  3. swift 闭包循环引用

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

  4. swift 闭包

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

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

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

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

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

  7. Swift闭包(Closure)

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

  8. swift闭包传值

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

  9. Swift 闭包表达式

    闭包是功能性自包含模块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C 中的 blocks 以及其他一些编程语言中的 lambdas 比较相似. 闭包的形式主要有三 ...

随机推荐

  1. MCS-51系列和80C51系列单片机是否相同

    MCS是Intel公司单片机的系列符号.Intel推出有MCS-48.MCS-51.MCS-96系列单片机. MCS-51系列单既包括三个基本型80C31.8051.8751,以及对应的低功耗型号80 ...

  2. YII 事件event和行为Behavior

    To declare an event in your CComponent child class, you should add a method with aname starting with ...

  3. 网络编程中几个地址结构与转换(in_addr,sockaddr,sockaddr_in,pcap_addr)

    man socket可以查看相关信息. socket头文件: #include <sys/types.h> /* See NOTES */ #include <sys/socket. ...

  4. 使用Userlock监控用户访问 增强学校网络安全

    随着网络技术的不断进步,一方面,拥有广泛教学资源的各大大中院校纷纷升级校园网络技术,保护学校的网络安全.另一方面,网络安全面临的威胁也层出不穷.面对来自网络内外的安全威胁,负责中小学.大学院校网络安全 ...

  5. 部分无线终端不响应键盘事件(keydown,keypress,keyup)的解决办法

    在无线侧实现搜索显示smartbox功能的时候,会对输入框绑定keydown.keyup.keypress事件,从而在检测到输入框的值发生改变时,发出请求拉取smartbox的内容. 但是,在iPho ...

  6. HDU_1009——老鼠的交易,性价比排序,最大化收益

    Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats guarding th ...

  7. linux命令-查看当前目录下所有文件的大小:“ll -h”

    //ll -h 命令只会显示文件的大小,而文件夹及其子目录或文件的大小不会显示.[root@hadoop01 soft]# ll -h total 2.1G -rw-r--r--. 1 root ro ...

  8. ORACLE_CLASS_ENDING

    [JSU]LJDragon's Oracle course notes In the first semester, junior year Oracle考前复习 试题结构分析: 1.选择题2x10, ...

  9. [转]Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...

  10. SMO启发式选择

    %% % svm 简单算法设计 --启发式选择 %% clc clear close all % step=0.05;error=1.2; % [data, label]=generate_sampl ...