currying - Curry all swift function parameters, but don't call the function -
i have following swift function:
func foo(bar: string)(_ baz: string) { nslog("bar \(bar), baz: \(baz)") } let f = foo("fizz")("buzz") // won't compile, foo returns void
i want pass dispatch_async
, can't because can't curry both parameters without invoking function. how curry both bar
, baz
without calling foo
?
if free change function declaration, heath's answer correct. if don't want that, need use inline closure, e.g.
// pre-existing foo definition func foo(bar: string)(_ baz: string) { nslog("bar \(bar), baz: \(baz)") } let f = { foo("fizz")("buzz") } f()
if problem want evaluate arguments immediately, can use capture list:
let f = { [a=bar(),b=baz()] in foo(a)(b) }
or when written call dispatch_async
:
dispatch_async(queue) { [a=bar(),b=baz()] in foo(a)(b) }
this works because capture list evaluated caller when closure created (as opposed being evaluated when closure invoked).
another option define nested curried function. nested functions sugar closures, can more convenient:
/// function code executing in func myfunc() { // ... // define nested function func f(bar: string, baz: string)() { foo(bar)(baz) } // call dispatch_async(dispatch_get_main_queue(), f("foo", "bar")) }
addendum: recommend against saying nslog("bar \(bar), baz: \(baz)")
. nslog
takes format string , arguments, , if either bar
or baz
contain looks format token (e.g. %@
or %d
) call nslog()
behave badly , possibly crash. have 2 reasonable options:
- say
nslog("%@", "bar \(bar), baz: \(baz)")
- say
nslog("bar %@, baz: %@", bar, baz)
the best option depends on whether arguments compatible cvararg
(which string
e.g. string?
not). note if arguments guaranteed not contain format tokens, such if they're numbers or booleans, can go ahead , use existing nslog("bar \(someintvar) baz \(someboolvar)")
style.
Comments
Post a Comment