您的位置:首页 > 移动开发 > Swift

Swift学习之闭包疑惑解析2

2014-07-06 10:07 253 查看
转载请保留原文链接:http://www.yiibai.com/swift/custom_operators.html

尾随闭包(Trailing Closures)

如果您需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。 尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
func someFunctionThatTakesAClosure(closure: () -> ()) {
// 函数体部分
}

// 以下是不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure({
// 闭包主体部分
})

// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
// 闭包主体部分
}


注意:

如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,您甚至可以把
()
省略掉。

在上例中作为
sort
函数参数的字符串排序闭包可以改写为:
reversed = sort(names) { $0 > $1 }

当闭包非常长以至于不能在一行中进行书写时,尾随闭包变得非常有用。 举例来说,Swift 的
Array
类型有一个
map
方法,其获取一个闭包表达式作为其唯一参数。 数组中的每一个元素调用一次该闭包函数,并返回该元素所映射的值(也可以是不同类型的值)。 具体的映射方式和返回值类型由闭包来指定。
当提供给数组闭包函数后,
map
方法将返回一个新的数组,数组中包含了与原数组一一对应的映射后的值。
下例介绍了如何在
map
方法中使用尾随闭包将
Int
类型数组
[16,58,510]
转换为包含对应
String
类型的数组
["OneSix", "FiveEight", "FiveOneZero"]
:
let digitNames = [
0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]

如上代码创建了一个数字位和它们名字映射的英文版本字典。 同时定义了一个准备转换为字符串的整型数组。
您现在可以通过传递一个尾随闭包给
numbers
map
方法来创建对应的字符串版本数组。 需要注意的时调用
numbers.map
不需要在
map
后面包含任何括号,因为其只需要传递闭包表达式这一个参数,并且该闭包表达式参数通过尾随方式进行撰写:
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output
number /= 10
}
return output
}
// strings 常量被推断为字符串类型数组,即 String[]
// 其值为 ["OneSix", "FiveEight", "FiveOneZero"]

map
在数组中为每一个元素调用了闭包表达式。 您不需要指定闭包的输入参数
number
的类型,因为可以通过要映射的数组类型进行推断。
闭包
number
参数被声明为一个变量参数(变量的具体描述请参看常量参数和变量参数),因此可以在闭包函数体内对其进行修改。闭包表达式制定了返回类型为
String
,以表明存储映射值的新数组类型为
String

闭包表达式在每次被调用的时候创建了一个字符串并返回。 其使用求余运算符 (number % 10) 计算最后一位数字并利用
digitNames
字典获取所映射的字符串。

注意:

字典
digitNames
下标后跟着一个叹号 (!),因为字典下标返回一个可选值 (optional value),表明即使该 key 不存在也不会查找失败。

在上例中,它保证了
number % 10
可以总是作为一个
digitNames
字典的有效下标 key。

因此叹号可以用于强制解析 (force-unwrap) 存储在可选下标项中的
String
类型值。

digitNames
字典中获取的字符串被添加到输出的前部,逆序建立了一个字符串版本的数字。 (在表达式
number % 10
中,如果number为16,则返回6,58返回8,510返回0)。
number
变量之后除以10。 因为其是整数,在计算过程中未除尽部分被忽略。 因此 16变成了1,58变成了5,510变成了51。
整个过程重复进行,直到
number /= 10
为0,这时闭包会将字符串输出,而
map
函数则会将字符串添加到所映射的数组中。
上例中尾随闭包语法在函数后整洁封装了具体的闭包功能,而不再需要将整个闭包包裹在
map
函数的括号内。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Swift