当用作函数中的参数时,swift闭包是否可以设置为默认值?

时间:2015-07-01 10:42:32

标签: ios macos swift

Swift函数非常方便的特性是函数参数可以有default values

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) {
}

有没有办法在调用success时强制开发者传递failuresendBody的值?

4 个答案:

答案 0 :(得分:33)

是的,函数只是您的值,因此您可以将它们作为默认值提供:

f.__proto__

或者,您可以将它们设为可选项,这样您就可以检测调用者是否通过了一个:

undefined

另外值得注意的是,如果你这样做:如果调用者使用尾随闭包语法,那么这将是参数列表中的 last 闭包。所以你希望最后一个是用户最想要提供的那个,这可能是成功的关闭:

// 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
)
{  }

除此之外,函数声明中的顺序与调用者无关 - 可以按任何顺序提供默认参数。

答案 1 :(得分:5)

你可以这样做,

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: )

您也可以调用所有变体,例如只传递上述方法中的一个参数,因为您必须使用命名参数调用它。

sendBody()
sendBody(body:)

sendBody(failure: )
sendBody(success:)

sendBody(body: , success: , failure: )

答案 2 :(得分:1)

我指定面向公众的闭包的首选方法 - 特别是您可能希望将其存储在以后的完成闭包 - 是为它们定义typealias,如下所示:

public typealias FooCompletion = (String) -> Void

然后在面向公众的功能中,您可以轻松地将其设为可选:

var onCompletion: FooCompletion? = nil

public func foo(completion: FooCompletion? = nil) {
    // Store completion for later
    onCompletion = completion
}

completion参数是可选的,因此允许它为nil,默认值为nil,这意味着调用者不必指定它。此外,因为您在多个地方使用该类型,如果您需要在开发期间更改其定义,那么只有一个地方可以这样做。它也很容易打电话:

private func someBackgroundThing() {
    var completionString = "done"
    ...
    onCompletion?(completionString)
}

答案 3 :(得分:0)

如何为功能参数设置默认值。 Swift 4和(可能)5。

func someFunction(age: Int, doSomething:@escaping () -> Void = {}){
  //do work here

  //
  doSomething()
}

那你就可以做到

someFunction(age: 18) {
  print("hello")
}

someFunction(age: 19)

您可能需要也可能不需要使用@escaping关键字。参见Swift @escaping and Completion Handler