2015-04-01 59 views
0

我有以下迅速函數:庫裏所有的快捷功能參數,但不調用函數

func foo(bar: String)(_ baz: String) { 
    NSLog("bar \(bar), baz: \(baz)") 
} 

let f = foo("fizz")("buzz") // won't compile, foo returns Void 

我想傳遞給dispatch_async,但我不能,因爲我不能既咖喱參數而不用調用該函數。如何在不致電foo的情況下同時烹飪barbaz

回答

5

如果隨意更改函數聲明,Heath's answer是正確的。如果你不想這樣做,那麼你只需要使用內聯閉包,例如

// pre-existing foo definition 
func foo(bar: String)(_ baz: String) { 
    NSLog("bar \(bar), baz: \(baz)") 
} 

let f = { foo("fizz")("buzz") } 
f() 

如果你的問題是你要立即評估參數,你可以使用一個捕獲列表:

let f = { [a=bar(),b=baz()] in foo(a)(b) } 

或者當作爲呼叫寫入dispatch_async

dispatch_async(queue) { [a=bar(),b=baz()] in 
    foo(a)(b) 
} 

這因爲在創建閉包時調用程序立即評估捕獲列表(而不是在調用閉包時進行評估)。

另一種選擇是定義一個嵌套的curried函數。嵌套功能是關閉真的只是糖,但他們可以更方便:

/// Function that your code is executing in 
func myFunc() { 
    // ... 

    // define a nested function 
    func f(bar: String, baz: String)() { 
     foo(bar)(baz) 
    } 

    // now call it 
    dispatch_async(dispatch_get_main_queue(), f("foo", "bar")) 
} 

附錄:我強烈反對說:NSLog("bar \(bar), baz: \(baz)")NSLog採用格式字符串和參數,因此如果barbaz包含任何看起來像格式標記的內容(例如%@%d),那麼對NSLog()的調用將表現不佳並可能崩潰。你有兩個合理的方案:

  1. NSLog("%@", "bar \(bar), baz: \(baz)")
  2. NSLog("bar %@, baz: %@", bar, baz)

最好的選擇取決於你的論點是否已經與CVarArg兼容(這String只是例如String?沒有)。另外請注意,如果您的參數保證不包含格式標記,例如它們是數字或布爾值,那麼您可以繼續使用現有的NSLog("bar \(someIntVar) baz \(someBoolVar)")樣式。

相關問題