作为函数中的参数使用时,可以将快速闭包设置为默认值吗?
Swift函数的一个非常方便的function是函数参数可以有默认值 :
func someFunction(parameterWithDefault: Int = 42) { //if no arguments are passed to the function call, //value of parameterWithDefault is 42 }
如果一个参数是一个闭包,有没有办法让它有一个默认值? 看下面的例子:
func sendBody( body: NSData? = nil, success: (data: NSData) -> Void, failure: (data: NSData?) -> Void) { }
有没有办法强制开发人员在调用sendBody
时传递success
或failure
的值?
是的,function只是你的价值,所以你可以提供他们作为默认值:
// just to show you can do it with inline closures or regular functions func doNothing<T>(t: T) -> Void { } func sendBody( body: NSData? = nil, success: (data: NSData) -> Void = { _ in return }, failure: (data: NSData?) -> Void = doNothing ) { }
或者,你可以使它们是可选的,这样你可以检测到调用者是否通过了一个:
func sendBody( body: NSData? = nil, success: ((NSData) -> Void)? = nil, failure: ((NSData?) -> Void)? = nil ) { success?(NSData()) } sendBody(success: { _ in print("ah, yeah!") })
另外值得注意的是,如果你这样做:如果调用者使用尾随闭包语法,这将是参数列表中的最后一个闭包。 所以你希望最后一个是用户最想提供的那个,这可能是成功的closures:
func sendBody( body: NSData? = nil, success: ((NSData) -> Void)? = nil, failure: ((NSData?) -> Void)? = nil ) { if success != nil { print("passed a success closure") } if failure != nil { print("passed a failure closure") } } // this prints "passed a failure closure" sendBody { data in print("which closure is this?") }
除此之外,函数声明中的顺序与调用方无关 – 可以按任何顺序提供缺省参数。
你可以做这样的事情,
let defaultSuccess: NSData -> Void = { (data: NSData) in } let defaultFailure: NSData? -> Void = { (data: NSData?) in } func sendBody( body: NSData? = nil, success: (data: NSData) -> Void = defaultSuccess, failure: (data: NSData?) -> Void = defaultFailure) { }
然后,您可以调用其中一种方法。 注意使用默认参数调用sendBody。
sendBody() sendBody(body: , success: , failure: )
你也可以调用所有的variables,比如只传递上面方法中的一个参数,因为你必须用named参数来调用它。
sendBody() sendBody(body:) sendBody(failure: ) sendBody(success:) sendBody(body: , success: , failure: )
我指定面向公用对象的首选方法 – 特别是可能要存储在某个地方的完成closures – 是为它们定义一个typealias
,如下所示:
public typealias FooCompletion = (String) -> Void
然后在公共的function,你可以很容易地使它是这样的可选:
var onCompletion: FooCompletion? = nil public func foo(completion: FooCompletion? = nil) { // Store completion for later onCompletion = completion }
completion
参数是可选的,所以允许nil
,默认值nil
,这意味着调用者不必指定它。 另外,因为你在多个地方使用这个types,所以如果你需要在开发过程中改变它的定义,那么只有一个地方可以这样做。 打电话也很容易:
private func someBackgroundThing() { var completionString = "done" ... onCompletion?(completionString) }