Swift之闭包

Swift之闭包

在这里插入图片描述
Swift开发文档中是这样介绍闭包的:闭包是可以在你的代码中被传递和引用的功能性独立模块。

闭包的形式有:

全局函数 嵌套函数 闭包表达式
有名字但不能捕获任何值。 有名字,也能捕获封闭函数内的值。 无名闭包,使用轻量级语法,可以根据上下文环境捕获值。

Swift中的闭包有很多优化的地方:

  1. 根据上下文推断参数和返回值类型
  2. 从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
  3. 可以使用简化参数名,如$0, $1(从0开始,表示第i个参数…)
  4. 提供了尾随闭包语法(Trailing closure syntax)

创建基本的闭包

let driving = {
  print("我要去开车")
}

上面的代码实际上创建了一个匿名的函数,并将这个函数赋给了 driving。之后你就可以把 driving() 当作一个常规的函数来用,就像这样:

driving()

在闭包中接收参数

当你创建闭包的时候,它们并没有名字,也没有提供书写参数的地方。但这并不意味着它们不能接收参数,只不过它们接收参数的方式稍有不同:这些参数是被写在花括号里面的。

为了让一个闭包接收参数,你需要在花括号之后把这些参数列出来,然后跟上一个in关键字。这样就告诉Swift,闭包的主体是从哪里开始的。

举个例子,我们来创建一个闭包,接收一个叫 place 的字符串作为唯一的参数,就像这样:

let driving = { (place: String) in
  print("我要开车去 \(place)。")
}

函数和闭包的一个区别是运行闭包的时候你不会用到参数标签。因此,调用 driving() 的时候,我们是这样写的:

driving("北京")

从闭包中返回值

闭包也能返回值,写法和闭包的参数类似:写在闭包内部, in 关键字前面。

还是以 driving() 闭包为例, 让它返回一个字符串。原来的函数是这样的:

let driving = { (place: String) in
  print("我要开车去  \(place)。")
}

改成返回字符串而不是直接打印那个字符串,需要 in之前添加 -> String,然后像常规函数那样用到 return 关键字:

let drivingWithReturn = { (place: String) -> String in
  return "我要开车去 \(place)。"
}

现在我们运行这个闭包并且打印出它的返回值:

let message = drivingWithReturn("北京")
print(message)

闭包作为参数

既然闭包可以像字符串和整数一样使用,你就可以将它们传入函数。闭包作为参数的语法乍一看一看挺伤脑筋的,让我们慢慢来。

首先,还是基本的 driving() 闭包。

let driving = {
  print("我正在开车。")
}

如果我们打算把这个闭包传入一个函数,以便函数内部可以运行这个闭包。我们需要把函数的参数类型指定为 () -> Void。 它的意思是“不接收参数,并且返回 Void”。在Swift中,Void是什么也没有的意思。

好了,让我们来写一个 travel() 函数,接收不同类型的 traveling 动作, 并且在动作前后分别打印信息:

func travel(action: () -> Void) {
  print("我准备出发了。")
  action()
  print("我到达目的地了。")
}

现在可以用上 driving 闭包了,就像这样:

travel(action: driving)

拖尾闭包语法

如果一个函数的最后一个参数是闭包,Swift允许你采用一种被称为 “拖尾闭包语法” 的方式来调用这个闭包。你可以把闭包传入函数之后的花括号里,而不必像传入参数那样。

又用到我们的 travel() 函数了。它接收一个 action 闭包。闭包在两个 print() 调用之间执行:

func travel(action: () -> Void) {
  print("我准备出发了。")
  action()
  print("我到达目的地了。")
}

由于函数的最后一个参数是闭包,我们可以用拖尾闭包语法来调用 travel() 函数,就像这样:

travel() {
  print("我正在开车。")
}

实际上,由于函数没有别的参数了,我们还可以将圆括号完全移除:

travel {
  print("我正在开车。")
}

拖尾闭包语法在Swift中非常常见,所以你要适应它。

版权声明:本文为weixin_48569975原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_48569975/article/details/106683882

智能推荐

Node.js安装配置

好久都没更新博客了,今天心血来潮,决定是时候更新一篇了,首先我们来认识一下node.js。 什么是node.js? 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的...

RocketMQ之双Master集群搭建笔记记录

一:RocketMQ双master集群部署 服务器环境(我采用的虚拟机,centos6 .5【特别注意:安装的虚拟机centos系统一定得是64位的,32位的会启动不起来。即便起来了也会有很多问题,深坑勿踩】)  ip       用户名    密码        角色     模式 192.168.197.101   root        nameServer1,brokerServer1  ...

蓝桥杯试题集-基础练习题-数列特征(Java)

//做题笔记,仅自己看得懂 题目: 正确姿势:...

多线程爬取4k超高清美图壁纸

多线程爬取4k美图壁纸 前言:看完此篇文章你可以更加深入的了解多线程的使用,并且最重要的你能够下载你自己想要的超高清4k壁纸 爬取结果: 1. 分析网站 要爬取的url :http://pic.netbian.com/ a) 判断网页是动态加载还是静态加载页面。右击查看网页源代码,按Ctrl + f在源代码中搜索网站的详情页地址,从而判断整个网页是静态加载的 b) 明确爬取的目标。我们要爬取的目标...

elementUI-添加自定义图标

elementui的小图标有限,跟UI给的不一样,这个时候咋办呢?百度走起。。。。参考了两篇博主分享的 自定义elementui中的图标 和 建立图标库,这里主要用到第一种 实际中: elementUI导航栏 具体代码: 汉字转换Unicode编码: 直接打开控制台: 汉字.chatCodeAt().toString(16); 然后回车; 至于三角形的图标,我直接把箭头的 unicode 值改成了...

猜你喜欢

[Linux]——文件缓冲区

文件缓冲区 提到文件缓冲区这个概念我们好像并不陌生,但是我们对于这个概念好像又是模糊的存在脑海中,之间我们在介绍c语言文件操作已经简单的提过这个概念,今天我们不妨深入理解什么是文件缓冲区。 为什么需要文件缓冲区 当我们在程序中写下一条printf语句时,我们希望将这条语句的内容打印到屏幕上。但是如果你将语句放在循环中,难道你执行一次循环那么操作系统就要打印一次这条数据么?答案当然不是 我们对于程序...

基于FPGA的IIC协议详解——EEPROM控制器(1)

IIC协议举例 常用IIC协议使用地方 常见IIC协议的注意点 24LC64芯片读写命令的时序图 eeprom控制器的系统框图 时序图设计 代码设计 EEPROM控制器测试模块的代码 结束语 常用IIC协议使用地方 熟悉一个协议一定要知道这个协议应该用到什么地方,IIC协议作为飞利浦公司定义的一个慢速传输协议,常用于: 1、芯片寄存器的配置; 2、eeprom的读写; 本次实验我们将使用eepro...

ssm 工程简易搭建(idea 工具下)

现在都流行springboot了,大部分都给你配合了了,可以快速开发。但是今天我们回顾一下ssm的搭建,其实也挺简单的,比刚入门那会觉得简单多了。 这个先讲几点: 1.开始搭建前,idea 自己要配置maven 和tomcat和jdk ,这里就不讲了。 2.为了简化配置,我们按照“约定优于配置”的原则(这种原则在sprigboot项目里面特别明显),启动项目时,项目有个文件...

oracle简单视图read only、check option和默认权限的异同(相对于DML语句)

视图分为俩类: 简单视图:   视图所代表的sql中如果没有group by语句,   没有组函数,查询的只有一张表,那么这样的视图就是简单视图. 复杂视图   视图所代表的sql中如果有group by语句,   或者有组函数,或者查询的是多张表,那么这样的视图就是复杂视图. s_emp表格属性 默认权限 1.可以插入不满足where条件的数据,原表也会更...

HTML5-简易Canvas绘图板

除了canvas以外,还用了一丢丢meta清除页面缓存,color类型和range类型的input控件。其他基本就一些鼠标响应事件了。总之就一个十分简易的canvas绘图板。贴个源码。 大概这个鬼样子。 火狐之类的浏览器可以直接右键保存绘制的图像为*.png不过我想的是用填充白色就不用写橡皮擦了所以整个画布都是填充了白色,存的*.png并不会有透明背景。...