作为函数中的参数使用时,可以将快速闭包设置为默认值吗?

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时传递successfailure的值?

是的,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) }