繁体   English   中英

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

[英]Can swift closures be set to a default value when used as a parameter in a function?

Swift 函数的一个非常方便的特性是函数参数可以有默认值

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的值?

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

// 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!") })

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

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

您还可以使用所有变体进行调用,例如在上述方法中仅传递一个参数,为此您必须使用命名参数调用它。

sendBody()
sendBody(body:)

sendBody(failure: )
sendBody(success:)

sendBody(body: , success: , failure: )

我首选的指定面向公众的闭包的方法——特别是你可能想要存储在某处以备日后使用的完成闭包——是为它们定义一个类型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)
}

如何为函数参数设置默认值。 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 和 Completion Handler

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM