爱程序网

【Swift 】- 闭包

来源: 阅读:

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

  

关于爱程序网 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助