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