swift闭包表达式和尾随闭包

Easter79
• 阅读 909

我们从一个Swift函数说起。并以此为例子。

Swift的标准库提供了一个叫做sorted(by:)的方法,会根据你提供的排序闭包将已知类型的数组的值进行排序。一旦它排序完成,sorted(by:)方法会返回与原数组类型大小完全相同的一个新数组,该数组的元素是已排序好的。原始数组不会被sorted(by:)方法修改。
我们以soted方法为例子,对一个数组进行排序,查看各种闭包表达到最后尾随闭包

//使用函数表达式作为参数,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
//构建排序逻辑,作为闭包传入sorted方法
func backward(num1 : Int, num2: Int) -> Bool {
    return num1 > num2
}
var reversedNumArr = numArr.sorted(by: backward)
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

闭包表达式语法能够使用常量形式参数、变量形式参数和输入输出形式参数,但不能提供默认值。可变形式参数也能使用,但需要在形式参数列表的最后面使用。元组也可被用来作为形式参数和返回类型。
我们使用闭包来代替backward函数,直接写一个符合sorted函数要求的闭包

//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
//构建一个入参为两个int类型,返回一个bool的闭包表达式,使用{}括起来
var reversedNumArr = numArr.sorted(by: {(num1: Int, num2: Int) -> Bool in
    return num1 > num2
})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

因排序闭包为实际参数来传递给函数,Swift能推断它的形式参数类型和返回类型(根据我们数组的类型,swift可以判断我们闭包需要的参数类型)
在numArr数组使用sorted时,sorted(by:)方法期望它的形式参数是一个(Int,Int)->Bool类型的函数。这意昧着(Int,Int)参数类型和Bool返回类型不需要被写成闭包表达式定义中的一部分,因为所有的类型都能被推断,返回箭头(->)和围绕在形式参数名周围的括号也能被省略

let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by: {(num1, num2) in
    return num1 > num2
})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

单表达式(浅显理解就只有一行代码,一个完整的表达)的函数或者闭包,我们可以将reture去掉。此叫做单表达式隐式返回

//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by: {num1, num2 in num1 > num2})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

swift自动对行内闭包提供简写实际参数名,使用$0,$1,$2此中类型来替代。也就是说我们可以不用专门声明num1和num2这种形参,可以直接使用$0和$2来取代num1和num2。所以既然闭包内可以使用$0和$1这种实际参数直接访问numArr的参数,我们也不必在闭包中声明(num1: Int, num2: Int)这中形式参数,然后我们的闭包表达式还可以再简写

//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by: {$0 > $1})
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

Swift的Int、float等还有String类型定义了关于大于号(>)的特定字符串实现,让其作为一个有两个相对应类型形式参数的函数并返回一个Bool类型的值。这正好与sorted(by:)方法的形式参数需要的函数相匹配。因此,你能简单地传递一个大于号,并且Swift将推断你想使用大于号特殊字符串函数实现

//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted(by:  > )
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

最后来到了我们的尾随闭包
如果你需要将一个很长的闭包表达式作为函数最后一个实际参数传递给函数,使用尾随闭包将增强函数的可读性。尾随闭包是一个被书写在函数形式参数的括号外面(后面)的闭包表达式。

//使用闭包表达式,对数组进行排序
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted{$0 > $1}
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

//自此我们排序从此变为最后的尾随闭包,更加简洁易读
let numArr = [5, 4, 6, 1, 7]
//构建排序逻辑,作为闭包传入sorted方法
func backward(num1 : Int, num2: Int) -> Bool {
    return num1 > num2
}
var reversedNumArr = numArr.sorted(by: backward)
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]

//使用尾随闭包
let numArr = [5, 4, 6, 1, 7]
var reversedNumArr = numArr.sorted{$0 > $1}
print(reversedNumArr) //输出:[7, 6, 5, 4, 1]
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Karen110 Karen110
3年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Easter79 Easter79
3年前
Swift讲解专题八——闭包
Swift讲解专题八——闭包一、引言      Swift中的闭包是有一定功能的代码块,这十分类似于ObjectiveC中的block语法。Swift中的闭包语法风格十分简洁,其作用和函数的作用相似。二、从一个系统函数看闭包      Swift标准函数库中提供了一个sort排序函数,对
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Wesley13 Wesley13
3年前
ES6 新增的数组的方法
给定一个数组letlist\//wu:武力zhi:智力{id:1,name:'张飞',wu:97,zhi:10},{id:2,name:'诸葛亮',wu:55,zhi:99},{id:3,name:'赵云',wu:97,zhi:66},{id:4,na
达里尔 达里尔
1年前
给数组添加新数据,判断数据是否重复
多选要进行数组拼接,希望判断往原数组里添的新数据是否重复,封装个简易方法languageconstdataArrayname:'aaa',id:1,name:'bbb',id:2;constnewDataname:'ccc',id:2;//要添加的新数
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k