概述
闭包是字包含的的函数代码快,可以在代码快中被传递和使用。早些年Objc时期,有面试官问我如何看待block
和 delegate
时候,个人比较倾向block的时候被提醒道:block会带来一些可读性和循环引用等问题。当然这也不能阻挡我对block的喜欢,最起码整洁度确实很好,有问题咱就搞清楚了。
闭包表达式
语法
{ (parameter) -> returnType in
// statements
}
根据上述表达式中可以看出闭包的函数体部分由in
关键字引入。
尾随闭包
ObjC
中有很多Block
作为函数参数的,在Swift 中闭包也是可以用作函数参数。作为参数的闭包,建议将闭包
作为最后一个实参
,增加可读性,我们将这种闭包称为尾随闭包
。
func operateCaculate(param1: Int, param2: Int, fun:(Int, Int) -> Int) {
print("result is \(fun(param1, param2))")
}
operateCaculate(param1: 1, param2: 2, fun: {$0 + $1})
// 作为尾随闭包我们可以将其优化为这样的写法
operateCaculate(param1: 2, param2: 3) {
$0 * $1
}
若尾随闭包为唯一参数时
func onePlusTwo(fn:(Int, Int) -> Int) {
print("onePlusTwo result is \(fn(1, 2))")
}
onePlusTwo(fn: {$0 + $1})
onePlusTwo() {$0 + $1}
onePlusTwo{$0 + $1}
忽略参数
func ignoreParams(fn:(Int, Int) -> Int) {
print(fn(3, 4))
}
ignoreParams{_, _ in 10}
自动闭包
我们来定义一个获取非空值的函数
func getUnnilValue(param1: Int?, param2: Int) -> Int {
if let reusult = param1 {
return reusult
} else {
return param2
}
}
print(getUnnilValue(param1: 1, param2: 2));
print(getUnnilValue(param1: nil, param2: 2));
因为param2
默认值是pram1
为空的时候才会加载,故我们使用函数类型的param2
让其延迟加载
func getUnnilValue1(param1: Int?, param2: ()-> Int) -> Int{
if let reusult = param1 {
return reusult
} else {
return param2()
}
}
print(getUnnilValue1(param1: 1, param2: {2}));
print(getUnnilValue1(param1: nil, param2: {2}));
但是这样的可读性优点差,Swift
给我们提供了自动闭包@autoclosure
来解决这个问题。
func getUnnilValue2(param1: Int?, param2:@autoclosure ()-> Int) -> Int{
if let reusult = param1 {
return reusult
} else {
return param2()
}
}
print(getUnnilValue2(param1: 1, param2: 2));
print(getUnnilValue2(param1: nil, param2: 2));
BTW
@autoclosure
注解 会自动将param2
的值2
分装成{2}
闭包@autoclosure
注解 只支持() -> T
格式