闭包是自包含带函数代码块,可以在代码中被传递和使用。我觉得可以这样理解:闭包相当于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. UDP协议----简单的CS模型实现

    UDP简单介绍 传输层主要应用的协议模型有两种,一种是TCP协议,另外一种则是UDP协议.TCP协议在网络通信中占主导地位,绝大多数的网络通信借助TCP协议完成数据传输.但UDP也是网络通信中不可或缺 ...

  2. 最牛技术 1秒启动Linux的窍门

    1秒启动Linux可以实现吗?我们知道Linux系统开机并不算快,最少也需要11秒,但是,现在有一个技巧,可以1秒打开linux系统,到底是什么技术这么牛?请看下文详细介绍 尽可能快的启动系统,对于自 ...

  3. import和import static的区别

    import static静态导入是JDK1.5中的新特性. 一般我们导入一个类都用 import 包名.类名; 而静态导入是这样:import static 包名.类名.*; 这里的多了个stati ...

  4. 关于ENABLE_BITCODE

    pod 'TSVoiceConverter' 如果,设置了工程target的ENABLE_BITCODE为NO.但是,在真机上运行时,仍然提示类似于如下错误: URGENT: all bitcode ...

  5. Android中Fragment的Hide和Show

    我们都知道,Fragment动态添加的时候我们可以使用FragmentTransaction的add和replace方法,replace方法就等效于对这个Fragment先执行remove(),再执行 ...

  6. Linux 查看进程基本命令

    https://www.cnblogs.com/zwgblog/p/5971455.html https://www.cnblogs.com/lcword/p/6046261.html https:/ ...

  7. LengthOfLastWord,字符串最后一个子串的长度

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  8. scala学习手记8 - 自适应的默认做法

    scala有一些默认做法,会让代码更简洁.更易读写,下面列出了这样几个特性: 1. 支持脚本.scala支持脚本,因此无须将所有的代码都放到类里.如果脚本可以满足需求,就将代码放到一个脚本里,无须再创 ...

  9. sql 生成随机数 以及不重复随机数

    背景:想在表中随机取10条记录,让取出来的数据不重复(表中必须是有个递增列,且递增从1开始间隔为1).  数据表: CREATE TABLE testable ( id INT  IDENTITY(1 ...

  10. android多国语言使用

    多国语言:在res目录下建立不同名称的values文件来调用不同的语言包 Values文件汇总如下: 中文(中国):values-zh-rCN 中文(台湾):values-zh-rTW 中文(香港): ...