When to use equal sign after declare a variable with closure in Swift -
i saw sample code apple:
let timeremainingformatter: nsdatecomponentsformatter = { let formatter = nsdatecomponentsformatter() formatter.zeroformattingbehavior = .pad formatter.allowedunits = [.minute, .second] return formatter }() var timeremainingstring: string { let components = nsdatecomponents() components.second = int(max(0.0, timeremaining)) return timeremainingformatter.stringfromdatecomponents(components)! }
the question is: constant , variable both declared closure, 1 equal sign, other not. why?
()
says "execute , return results." long-winded answer:
let timeremainingformatter: nsdatecomponentsformatter = { // ... }() // <- '()' means "execute , give me formatter"
timeremainingformatter
calculated once, @ init time, , value stored. parenthesis indicates closure should executed , results returned, in case stored property.
var timeremainingstring: string { // ... }
timeremainingstring
calculated each time called.
functions vs. closures
more generally, in swift, functions named closures. defining function like:
func myfunc() -> void { print("function") }
is pretty same defining closure like:
let myclosure: () -> void = { print("closure") }
in both cases, have name (myfunc
/myclosure
), call signature(() -> void
), , block of code ({ print(...) }
).
just call function:
myfunc()
you call stored closure like:
myclosure()
and both print.
functions pretty convenience defining named closures.
using functions , closures in context
let's had global function , global stored closure, defined respectively as:
func myintfunc() -> int { return 1 } let myintclosure: () -> int = { return 2 }
the similarities should pretty obvious.
now want use them in class properties. you'd do
class myclass { let funcint: int = myintfunc() // resolve 1 let closureint: int = myintclosure() // resolve 2 }
notice how have ()
@ end of both of those. says "execute function/closure int
now."
now imagine don't want define global closure; you'd rather put code in class, keep things organized. do:
class myclass { let funcint: int = myintfunc() // resolve 1 let closureint: int = { return 2 }() // resolve 2 }
you still need execute closure int
out of it, function. place ()
after it, function.
calculated properties
lastly, touch on "calculated property".
var timeremainingstring: string { // ... }
you can think of way of writing function takes no arguments, , short-cut call signature (you can treat property). it's closure being stored property, because special notation, swift knows execute closure , returns result every time call property. "calculated property".
when call:
let timeremaining = instance.timeremainingstring
swift translating to:
let timeremaining = instance.timeremainingstring()
it's adding ()
make stored closure execute.
things little more complicated that, because can define setter closures along getters we've discussed, , observer closures well. swift dispatch correct closure depending on kind of operation you're trying perform.
Comments
Post a Comment