从??(空合运算符)看autoclosure

2017-08-03  本文已影响14人  litt1err

## 1:autoclosure初识

先看一下书上的解释:自动闭包是一种自动创建的闭包,用于包装传递给函数作为参数的表达式。这种闭包不接受任何参数,当它被调用的时候,会返回被包装在其中的表达式的值。这种便利语法让你能够省略闭包的花括号,用一个普通的表达式来代替显式的闭包。

简单来说,就是把你传入的参数自动包装成闭包,再传给对应的函数

写个简单的例子

给定一个数组,定义一个闭包每次调用移除数组里面第一个元素

1.正常闭包调用

var strArray =["1", "2", "3", "4", "5"]

let removeObj = { strArray.remove(at: 0) }

func removeStr(remove removeObj: () -> String) {

print("Now remove \(removeObj())!")

}

removeStr { () -> String in

removeObj()

}

2.转成自动闭包

func removeStr(remove removeObj: @autoclosure () -> String) {

print("Now remove \(removeObj())!")

}

removeStr(remove: strArray.remove(at: 0))

这时候我们传入的strArray.remove(at: 0)表达式返回值是一个String,系统会自动的把他转成一个闭包{strArray.remove(at: 0)}.

## 2:??(空合运算符)

先看下源码

public func ??(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T

optional: T? ----第一个参数是一个可选类型T?

defaultValue: @autoclosure () throws -> T ----- () throws -> T是一个函数,很好,非常可以理解,optional是可选型,万一是nil我们就用默认值(defaultValue)重点来了@autoclosure就是我们要的可选闭包的关键字了。有了这个我们上面1中简述的一样,可以在调用??函数时我们传入一个表达式就ok了

要是不理解我们可以自己实现一个??(运算符重载)来验证一下

func requestToken() -> String?{

return nil

}

let token = requestToken() ?? "defaultToken"//打印defaultToken

func ??(optional: T?, defaultValue: @autoclosure () -> T)-> T{

if let value = optional{ return value }

return defaultValue()

}

如果不是autoclosure我们在??后面传的应该是一个闭包

上一篇 下一篇

猜你喜欢

热点阅读