我给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. hdu 3435 A new Graph Game

    http://acm.hdu.edu.cn/showproblem.php?pid=3435 #include <cstdio> #include <iostream> #in ...

  2. ural 1837 Isenbaev's Number

    http://acm.timus.ru/problem.aspx?space=1&num=1837 #include <cstdio> #include <cstring&g ...

  3. USB 0xC0000012 错误详解

    0xC0000012Bus Hound 6.01 capture on Windows Vista Service Pack 1 (x86). Complements of www.perisoft. ...

  4. BZOJ3315: [Usaco2013 Nov]Pogo-Cow

    3315: [Usaco2013 Nov]Pogo-Cow Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 143  Solved: 79[Submit] ...

  5. HDU_2049——部分错位排列,概率论

    Problem Description 国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎",具体的操作是这样 ...

  6. openStack 手动部署文档

    1, 规划配置网络

  7. 为什么选择Premium Fabric Shanghai

    展商首页 为什么选择Premium Fabric Shanghai

  8. python 学习资料

    Python是一种面向对象.直译式计算机程序设计语言.它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用縮进来定义语句块.与Scheme.Ruby.Perl ...

  9. poj 2104 K-th Number - 经典划分树

    Description You are working for Macrohard company in data structures department. After failing your ...

  10. [iOS]使用symbolicatecrash分析crash文件

    对于我们iOS开发者来说,最心碎的事莫过于苹果审核一个星期后上架app store,而第二天就报出闪退bug.一周前我刚经历过,而且最坑的是由于第一次做个人开发,经验不足,没有集成友盟的分析SDK,还 ...