在Swift中使用尾闭包浅析
如果一个函数(包括构造函数)接受多个输入参数,其中有一个或者多个参数是闭包类型, 这些闭包类型中的最后一个称为尾闭包。对于尾闭包,Swift提供了语法糖 ,允许写出更加简洁和自然的代码。
举例来说,下面代码定义的函数fetchData()
有两个参数,其中第二个参数 resultHandler
是一个闭包类型, 该参数允许调用者对fetchData()
的结果做不同的处理,有的可能仅仅打印一下,有的可能记录日志,有的可能将处理结果写到数据库等等。
enum Result
{
case success
case error
}
func fetchData(strUrl:String,resultHandler: (Result)-> Void )
{
//这里是fetchData的处理逻辑
//处理完毕,调用resultHandler
resultHandler(.success)
}
下面是调用该函数的正常语法:
fetchData(strUrl:"http://www.blog.csdn/",
resultHandler:{ result in
switch result
{
case .success:
print("fetchData success")
case .error :
print("fetchData error")
}
}
)
下面是使用尾闭包语法糖的后的调用语法:
fetchData(strUrl:"http://www.blog.csdn/")
{ result in
switch result
{
case .success:
print("fetchData success")
case .error :
print("fetchData error")
}
}
比较二者的调用方式,可以看到,使用语法糖后,首先去掉了闭包参数的名称,其次,将闭包逻辑和其他参数分离,直接写在正常代码块的位置,闭包代码犹于正常的程序代码一般,不仅简洁,而且自然。
如果函数仅仅只有一个闭包参数,比如,假设上面的fetchData
没有strUrl
参数,则上述调用语法还可以进一步简化。如下:
//定义函数
func fetchData(resultHandler: (Result)-> Void )
{
//这里fetchData的处理逻辑
//处理完毕,调用resultHandler
resultHandler(.success)
}
//使用函数
fetchData { result in
switch result
{
case .success:
print("fetchData success")
case .error :
print("fetchData error")
}
}
可以看到,表示函数调用参数的小括弧对()
也可以省略了。
如果一个函数有多个闭包参数,那么对尾闭包参数或者首闭包参数,我们可以使用上述闭包语法,但对非首尾闭包参数,只能按普通方式调用语法书写。还是以上面的fetchData()
函数为例,修改该函数,使它接收两个闭包,然后考察其不同的调用方式。如下示例:
//定义函数
func fetchData(successHandler:()->Void,errorHandler: (_ error: String) -> Void )
{
//这里fetchData的处理逻辑
//处理完毕
var success = false
if success
{
successHandler()
}
else
{
errorHandler("网络错误")
}
}
//使用函数,正常语法调用
fetchData(
successHandler: { print("fetchData success") } ,
errorHandler:{ error in
print("fetchData error\(error)")
} )
//使用尾闭包语法糖,方式一
fetchData(
successHandler:
{ print("fetchData success") })
{ error in
print("fetchData error\(error)")
}
//使用首闭包语法糖,方式二
fetchData
{ print("fetchData success") }
errorHandler:
{ error in
print("fetchData error\(error)")
}
可见,这种情况下,即便使用了尾闭包或者首闭包语法糖,代码可读性的改进并不明显,特别是方式一,貌似更加混乱。这提示我们,在设计函数时,尽量最多只包含一个闭包参数,这样才能够充分发挥尾闭包的便利性。
可以用一首古诗形容使用尾闭包的感觉:
好雨知时节,当春乃发生
随风潜入夜,润物细无声