闭包是自包含带函数代码块,可以在代码中被传递和使用。我觉得可以这样理解:闭包相当于C#中的lambda表达式;

全局函数和嵌套函数,实际也是特殊的闭包。

通常闭包是以下三种形式:

a,全局函数是一个有名字但不会捕获任何值的闭包

b,嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包

c,闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包

1,闭包基本语法(Closure Expression Basic Syntax)

例子:sorted函数

Swift 标准库提供了sorted函数,会根据您提供的基于输出类型排序的闭包函数将已知类型数组中的值进行排序,排序完成,函数会返回一个排序后的数组

sorted 的重载的第二个参数isOrderedBefore 就是要传入闭包函数,该闭包函数需要传入与数组类型相同的两个值,并返回一个布尔类型值来告诉sorted函数当排序结束后传入的第一个参数排在第二个参数前面还是后面。

true: 第一个参数排在前面

false:第一个参数排在后面

我们将数组从小到大排序,可以直接使用sorted函数,

var arr:[Int]=[1,2,9,0,7,4,8,3,5,2];
sorted(arr)
//[0, 1, 2, 2, 3, 4, 5, 7, 8, 9]

从大到小就麻烦点了,相当于用上了C#的委托,将方法作为参数传入另一个方法里执行

func compareInt(a:Int,b:Int)->Bool{
return a>b;
}
sorted(arr,compareInt);
//[9, 8, 7, 5, 4, 3, 2, 2, 1, 0]

现在用闭包的方式写,匿名函数代替了上面的compareInt函数

sorted(arr, {(a:Int,b:Int)->Bool
in return a>b;})

闭包表达式语法:

{ (parameters) -> returnType in
statements
}

闭包的函数体部分由关键字in引入。 该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始。闭包函数体不需要使用大括号包住。

2,简化语法(Simplify Syntax)

2.1,根据上下文推断类型

sorted 传入排序闭包函数时,Swift其实是可以推断参数和返回值类型的,在前面的例子中,当传入第一个参数是int数组的时候,Swift就会推断出第二个参数类型就应该是(Int,Int)->Bool的函数,因此Int,Int和Bool类型并不需要作为闭包表达式定义中的一部分。

可以简写成:

sorted(arr, {a,b in return a>b});

2.2,单表达式闭包隐式返回

意思就是,当 in 后面(即函数体) 只有一句表达式时可以省略return关键字。

即:

sorted(arr, {a,b in a>b});

2.3,参数名称缩写

Swift 自动为内联函数提供了参数名称缩写功能,您可以直接通过$0,$1,$2来顺序调用闭包的参数。不需要自定参数名称。in关键字也同样可以被省略,因为此时闭包表达式完全由闭包函数体构成:

sorted(arr, {$0>$1});

2.4,运算符函数

难以想象,居然还有一种更简短的方式来撰写上面例子中的闭包表达式,您可以简单地传递一个大于号,Swift可以自动推断出您想使用大于号的函数实现:

sorted(arr, >);

3,尾随闭包(Trailing Closures)

如果您需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。 尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。

在上例中作为sorted函数参数的整数排序闭包可以改写为:

sorted(arr){$0>$1}

4,捕获值(Capturing Values)

闭包可以在其定义的上下文中捕获常量或变量。

下面是一个将整型数据按照  越靠近5的整数排前面 的一个排序方法

var arr1=[0,1,2,3,4,5,6,7,8,9,10];
arr1=sorted(arr1){fabs(Float($0-5))<fabs(Float($1-5))}
//输出:[5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10]

这是用硬编码的方式,如果我们要根据用户输入而决定排序方式->即指定一个变量来代替硬编码部分,使方法有比较好的扩展性

方法很简单,在闭包外部定义变量,闭包内可以直接使用:

var num=7;
arr1=sorted(arr1){fabs(Float($0-num))<fabs(Float($1-num))}
arr1

  

【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 中的闭包一个定义:闭包是自包含的匿名函数代码块,可以作为表达式.函数参数和函数返回值,闭包表达式的运算结果是一种函数类型. Swift中的闭包类似于Objective-C中的代码块.J ...

  10. Swift 闭包表达式

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

随机推荐

  1. 20145229吴姗珊逆向BOF实践

    20145229吴姗珊逆向BOF实践 实践 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. ...

  2. Arcgis Javascript API 开发笔记

    JS API3.4的要求 à(1)  IE9或以上版本 否则dijit1.8.3不匹配 1.如何发布ArcgisJavascript API应用 0.准备工作: (1).有web应用: (2).有js ...

  3. iOS 10 系统 AVPlayer视频播放不了问题解决

    使用[AVAudioPlayer Play]时出现了异常... 由于xcode中设置了当所有异常出现时的断点,,解决办法是将all改为Objective-C: libc++abi.dylib`__cx ...

  4. Spring_Bean 之间的关系

    beans-relation.xml <?xml version="1.0" encoding="UTF-8"?><beans xmlns=& ...

  5. quartz(3)--spring整合quartz入门案例

    第一步:导入jar <!-- quartz --> <dependency> <groupId>org.quartz-scheduler</groupId&g ...

  6. Hibernate常见优化策略

    ① 制定合理的缓存策略(二级缓存.查询缓存). ② 采用合理的Session管理机制. ③ 尽量使用延迟加载特性. ④ 设定合理的批处理参数. ⑤ 如果可以,选用UUID作为主键生成器. ⑥ 如果可以 ...

  7. bootstrap正则表达式验证手机 座机 邮箱

    $('#CusForm').bootstrapValidator({ fields : { //验证手机 'customer.mobile' : { //input中的name 值 validator ...

  8. Node.js 项目的配置文件

    在 Node.js 中可以通过process.env来访问当前的环境变量信息,比如: { PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin', T ...

  9. U盘安装XP

    ZC: 第1阶段结束 进入第2阶段 的时候,还是需要手动选择USB启动 (如果没有修改BIOS为USB启动的话) ZC: 我用的 WinSetupFromUSB,是文章尾部的那个版本的软件界面. ZC ...

  10. jquery的50个免费插件

    说不定什么时候用到呢 http://www.admin10000.com/document/4711.html