簡體   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