闭包是自包含带函数代码块,可以在代码中被传递和使用。我觉得可以这样理解:闭包相当于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. 一些好用的Linux命令工具

    刚好看到一个系列的博文,讲的就是那些平时很少被人用到但是很实用的命令,选一些觉得自己应该比较常用到的出来写个笔记. 这些命令有些不是系统命令,需要自行下载安装.Debian下安装:sudo apt-g ...

  2. uiautomator--图像处理

    一.图像处理在自动化中使用场景 1)效果类截图  图像处理技术在自动化的场景中很容易使用到.自动化不是万能的,有时候效果类的是无法进行验证的,但是效果类一般会有图像显示,我们可以通过截图对比实现. 2 ...

  3. 周立功CAN-II引脚图

    注意:如果需要两个CAN通道通信,直接用杜邦线将L连L,H连H,地连地就行(3.6引脚已做短接处理),不需要反接

  4. 安装 SPRING TOOL SUITE

  5. Google maps api demo

    demo: <!DOCTYPE html> <html> <head> <meta name="viewport" content=&qu ...

  6. 关于MySQL的TinyInt数据类型在Delphi中作为Boolean类型的一个要注意的问题

    关于MySQL的TinyInt数据类型在Delphi中作为Boolean类型的一个要注意的问题: 在定义TinyInt类型字段时,若要作为Delphi中作为Boolean类型,则该字段的长度必须为1!

  7. Java IO操作——数据操作流DataOutputStream和DataInputStream的使用

    学习目标  掌握DataOutputStream和DataInputStream的作用 可以使用DataOutputStream和DataInputStream写入和读入数据 数据操作流 在io包中, ...

  8. linux ioctl()函数

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...

  9. BZOJ4455/UOJ185 [Zjoi2016]小星星

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  10. scjp考试准备 - 9 - 多态

    题目为如下代码的执行结果: abstract class Vehicle{ public int speed(){ return 0; } } class Car extends Vehicle{ p ...