在Swift中,可以通过func定义一个函数,也可以通过闭包表达式定义一个函数!

一、闭包表达式

概念

闭包表达式与定义函数的语法相对比,有区别如下:

  1. 去除了func
  2. 去除函数名
  3. 返回值类型添加了关键字in
  4. { }放在形参列表的前边

闭包表达式的形式如下:

{ 

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

     函数体代码

 }

讲解

举例1  闭包表达式作为变量或者常量的值

调用闭包表达式不需要写参数v1,v2,直接调用fn0(10,20)就可以

举例2 闭包表达式作为函数的返回值

举例3 闭包表达式作为函数的实参

下面讲述sorted(by:)方法定义和语法优化方式,来展示闭包表达式不同的表达方式达到同样的效果!

讲述之前先简单介绍下sorted方法, Swift标准库提供了sorted(by:)方法,会将已知类型数组中的值进行排序. 一旦进行了排序会返回和原数组大小相同,包含同类型元素并且是正确排序的数组,如例3.

sorted(by:)方法接受一个闭包,该闭包函数需要传入元素类型的两个值,并返回Bool值,完成排序,排序闭包函数类型需为(String, String) -> Bool

在上面的两种写法中,都写成了(String, String) -> Bool, 在闭包表达式中函数和返回值类型都写在了大括号内,而不是大括号之外.

下面不断简化的如下

let arr = ["hello","world","guohai"]
///闭包表达式当做参数
//写法一
let sortArr0 = arr.sorted{(str1: String, str2: String) -> Bool in
return str1 < str2
}
//写法二: 省去了参数类型
let sortArr1 = arr.sorted{(str1, str2) -> Bool in
return str1 < str2
}
//写法三: 如果返回值是单一表达式,可省去return
let sortArr2 = arr.sorted{(str1, str2) -> Bool in
str1 < str2
}
//写法四: 如果编译器可以确定返回值,可以去除返回值类型
let sortArr3 = arr.sorted{(str1, str2) in
str1 < str2
}
//写法四: Swift闭包表达式可以不明显写出参数名,可以用美元符$表示
let sortArr4 = arr.sorted{$ < $}
//写法五: 编译器,对于$0 < $1和直接<效果一样
let sortArr5 = arr.sorted(by: <)

尾随闭包

如果将很长的闭包表达式作为函数的最后一个实参,使用尾随闭包可以增强函数的可读性

尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式

如果闭包表达式是函数的唯一实参,而且使用了尾随闭包的语法, 那就不需要在函数名后写圆括号

二、闭包

闭包: 一个函数和它所捕获的变量/常量环境组合起来

  • 一般指定义在函数内部的函数
  • 一般它捕获的是外层函数的局部变量/常量

看如下闭包,返回的plus和num形成了闭包

typealias Fn = (Int) -> Int
func getFn() -> Fn {
var num =
func plus(_ i: Int) ->Int {
num += i
return num
}
return plus
}
var fn = getFn()
print(fn())
print(fn())
print(fn())
print(fn())

如果大家看不出上面的结果,可以将var num = 0放在外面是全局变量,如下

全局变量num时,结果是不断的叠加,如果还是回到上一个,将num = 0移植到函数内部变成局部变量,和plus形成闭包,结果又如何呢?

发现结果是一样的,下面来探究本质!

查看上面代码汇编代码如下

上面四次fn操作,调用访问的同一内存num,因为闭包的作用将局部变量num放进了堆空间,所以num不会被销毁!

拓展:(iOS底层堆空间分配的大小是16的倍数--常识)

Swift --闭包表达式与闭包(汇编分析)的更多相关文章

  1. 【Swift学习】Swift编程之旅---闭包(十一)

    闭包是可以在代码中被传递和使用的自包含功能模块,它很像c和oc中的block,和.net中的lambdasbas表达式. 闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 包裹着这些常量和变量的 ...

  2. Swift:函数和闭包

    函数 函数是一个完成独立任务的代码块,Swift中的函数不仅可以像C语言中的函数一样有函数的参数和返回值,而且还支持嵌套,并且有函数参数默认值.可变参数等. //定义一个函数,注意参数和返回值,如果没 ...

  3. The Swift Programming Language-官方教程精译Swift(8)闭包 -- Closures

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

  4. Swift使用闭包表达式

    Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in    语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是 ...

  5. Swift的闭包(一):闭包简介、闭包表达式的优化

    定义:Closures are self-contained blocks of functionality that can be passed around and used in your co ...

  6. Swift 闭包表达式

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

  7. C# 从CIL代码了解委托,匿名方法,Lambda 表达式和闭包本质

    前言 C# 3.0 引入了 Lambda 表达式,程序员们很快就开始习惯并爱上这种简洁并极具表达力的函数式编程特性. 本着知其然,还要知其所以然的学习态度,笔者不禁想到了几个问题. (1)匿名函数(匿 ...

  8. swift学习笔记之-闭包

    //闭包 import UIKit /*闭包(Closures): 函数.闭包.类都是引用类型(引用类型的实例赋值给变量或常量时,得到的都是该实例的引用,而值类型的实例变量得到的是独立的值的拷贝) 1 ...

  9. Swift应用案例 2.闭包入门到精通

      本文主要介绍Swift的闭包的使用并与OC的Block做比较.学习Swift是绕不过闭包的,因为无论是全局函数还是嵌套函数都是闭包的一种,本文主要介绍闭包表达式. 1.闭包表达式的使用 // 1. ...

随机推荐

  1. 基于rtmp的移动端推流解决方案

    因工作需要,及考虑成本因素,需要探索一套免费的移动端基于rtmp推流的直播解决方案,过程虽稍显曲折,但最终还是完成了目标.在这里将记录下来,以便日后查阅. 总体思路 移动端推流(RTMP) ---&g ...

  2. 24)PHP,数据库的基本知识

    (1)数据库操作的基本流程: • 建立连接(认证身份) • 客户端向服务器端发送sql命令 • 服务器端执行命令,并返回执行的结果 • 客户端接收结果(并显示) • 断开连接 (2)php中操作数据库 ...

  3. 计算机数制与IPv4

    常用计数:十进制数 1010D.二进制 1010B.十六进制1010H 计算机数制: 数制组成=每一位上的数字*该位的值 IPV4地址一共32bit 人使用点分十进制的方式来进行记忆 IPv6地址一共 ...

  4. springboot学习笔记:10.springboot+atomikos+mysql+mybatis+druid+分布式事务

    前言 上一篇文章我们整合了springboot+druid+mybatis+mysql+多数据源: 本篇文章大家主要跟随你们涛兄在上一届基础上配置一下多数据源情况下的分布式事务: 首先,到底啥是分布式 ...

  5. 四、RabbitMQ Exchange类型

    RabbitMQ整体上是一个生产者与消费者模型,主要负责接收.存储和转发消息.可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ就好 ...

  6. 阿里云系统安装部署Freeswitch

    1.安装vim apt-get install vim 2.修改镜像源 将/etc/apt/source.list的原有源注释掉,添加下面的源: deb http://mirrors.163.com/ ...

  7. highcharys去掉x轴,y轴轴线和刻度

    x轴 xAxis: { lineWidth :,//去掉x轴线 tickWidth:,//去掉刻度 labels: { enabled: false },//去掉刻度数字 }, y轴 yAxis: { ...

  8. 用磁盘工具刻录MACOSX系统启动盘方法

    些系统盘用Toast 刻录后无法引导,建议使用磁盘工具刻录系统盘 老手可能早知道这了,仅供新手参考 在应用程序-->实用工具里找到磁盘工具,打开. 将DMG文件拖放到磁盘工具窗口,双击DMG文件 ...

  9. python的collections模块和functools模块

    collections是Python内建的一个集合模块,提供了许多有用的集合类. namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: >>> ...

  10. Excel中带字母的数字序列自增实现方法

    示例: 在A1单元格输入以下公式,然后向下填充公式 =".mr"&ROW()&" {margin-right: "&ROW()& ...