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

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -