柯里化所有 swift 个函数参数,但不调用该函数
Curry all swift function parameters, but don't call the function
我有以下 swift 功能:
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
的情况下同时咖喱 bar
和 baz
?
Append an extra set of parens at the end of the function declaration:
func foo(bar: String)(baz: String)() {
NSLog("bar \(bar), baz: \(baz)")
}
let f = foo("fizz")("buzz") // compiles!
f() // logs: "bar fizz, baz: buzz"
如果你随意更改函数声明,是正确的。如果你不想那样做,那么你只需要使用一个内联闭包,例如
// 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)
}
这是有效的,因为调用者在创建闭包时立即评估捕获列表(而不是在调用闭包时评估)。
另一种选择是定义嵌套柯里化函数。嵌套函数实际上只是闭包的糖分,但它们可以更方便:
/// 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
采用格式字符串和参数,因此如果 bar
或 baz
包含任何看起来像格式标记的内容(例如 %@
或 %d
),则对 NSLog()
的调用将表现不佳并可能崩溃。您有两个合理的选择:
- 说
NSLog("%@", "bar \(bar), baz: \(baz)")
- 说
NSLog("bar %@, baz: %@", bar, baz)
最佳选择取决于您的参数是否已经与 CVarArg
兼容(String
兼容,但例如 String?
不兼容)。另请注意,如果保证您的参数不包含格式标记,例如它们是数字或布尔值,那么您可以继续使用现有的 NSLog("bar \(someIntVar) baz \(someBoolVar)")
样式。
我有以下 swift 功能:
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
的情况下同时咖喱 bar
和 baz
?
Append an extra set of parens at the end of the function declaration:
func foo(bar: String)(baz: String)() {
NSLog("bar \(bar), baz: \(baz)")
}
let f = foo("fizz")("buzz") // compiles!
f() // logs: "bar fizz, baz: buzz"
如果你随意更改函数声明,
// 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)
}
这是有效的,因为调用者在创建闭包时立即评估捕获列表(而不是在调用闭包时评估)。
另一种选择是定义嵌套柯里化函数。嵌套函数实际上只是闭包的糖分,但它们可以更方便:
/// 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
采用格式字符串和参数,因此如果 bar
或 baz
包含任何看起来像格式标记的内容(例如 %@
或 %d
),则对 NSLog()
的调用将表现不佳并可能崩溃。您有两个合理的选择:
- 说
NSLog("%@", "bar \(bar), baz: \(baz)")
- 说
NSLog("bar %@, baz: %@", bar, baz)
最佳选择取决于您的参数是否已经与 CVarArg
兼容(String
兼容,但例如 String?
不兼容)。另请注意,如果保证您的参数不包含格式标记,例如它们是数字或布尔值,那么您可以继续使用现有的 NSLog("bar \(someIntVar) baz \(someBoolVar)")
样式。