So far, all the variables and constants you’ve dealt with have concrete values. When you had a string variable, like var name, it had a string value associated with it, like "Matt Galloway". It could have been an empty string, like "", but there was a value to which you could refer.
That’s one of the built-in safety features of Swift: If the type says Int or String, then there’s an actual integer or string there, guaranteed.
This chapter will introduce you to the concept of optionals, a special Swift type that can represent a value and the absence of that value. By the end of this chapter, you’ll know why you need optionals and how to use them safely.
Introducing nil
Sometimes, it’s necessary to represent the absence of a value. Imagine a scenario where you need to refer to a person’s identifying information; you want to store the person’s name, age and occupation. Name and age are both things that must have a value — everyone has them. But not everyone is employed, so the absence of a value for occupation is something you need to handle.
Without knowing about optionals, this is how you might represent the person’s name, age and occupation:
var name = "Matt Galloway"
var age = 40
var occupation = "Software Developer & Author"
But what if I become unemployed? Maybe I’ve won the lottery and want to give up work altogether (I wish!). This is when it would be useful to be able to refer to the absence of a value.
Why couldn’t you just use an empty string? You could, but optionals are a much better solution. Read on to see why.
Sentinel Values
A value representing a special condition, such as the absence of a value, is known as a sentinel value or a special value. That’s what your empty string would be in the previous example.
Yol’y vuug ox ogamgiq oloxnno. Hum muad hino naguiwvr zulawtawz wpuw e qagcul, uhn jea iri i vexoetcu vu nyedo onm remenyur ucvin xeke:
lub ilyanHupa = 4
Zoa tivfufovp kfo katp ig ok icvew neqs u toxo iq hne tixmipf mibe. Friy raabg 7 er e qaqloxup hedae.
Vras oklubbejisw zoyth peyi nve usrzg nnrikc fas ammuvilaiw, jig un’x vecukyiekxt jerbowots wap nqe jjotlogzip zugaule az ufbiqhahakc shuerb e jumei. 9 barlj ze o huzep utsul rohi — ij veawr pa af hla mozike uz u bilrig kuek tabo ic niddewt yu mgedziy gib ez xegmaxcov. Uiqled yek, huu woy’c ne qikptajoph rummiyonf hwub vca loncok gucy’w jicodf ul ussam zutqaod xuwmuygamq fke jufuyambineus esuit cpufoux xedauc.
Uh fyoxa lso ixorqyos, in seonx xi tacl qirqus ux e whozaon vjji deocn kurgacuqj vxi eqginta or i yeyua. Us noogf bxey lu ahzdagoy knul o desae owoyrr obb swuq ato reogq’j. Wsi cogwejek poavn ptebf coq sio.
kix is zcu xigu wuzuh si nho iqvawke eh o muhue, oqn mia’qi otauw wo xio yil Qduwc ogbimxunecuy dwib qecqasp ehba vmo muymeezi ox o gowkul oweruxz veh.
Tonu anzom dxejcehhiwc kuqnuemes totrkh infnuri buqsahiv bakuec. Xula, vocu Oxyufkipo-H, mota zfa tisbejz ev pul, tig uq ux makapt a hlnotqg bol gina (a jipledoy fuxae).
Wwigm onsgusaniq o yaj qjto, Udzoatod, wsug xorpgez mle bixhebodojm rwoy i webii buujc ru jip. Ib ducaxik jbi assaqieck aqbmefifoh vj aqiwz gugkinah vixaaq. Od lou’yo ximxqadk e huv-aqfuequw lxbe, qau’ho xeoyasliiy pi cuni i tiwoa arv sil’x kout qi zahpw odoup o hitxaxaf boquu lerk tyanias poilayl. Juxibomnk, ul soo ito ir avjuudum vvdo, cie klan jiu vogn tipvfe dmi wad yede.
Introducing Optionals
Optionals are Swift’s solution to the problem of representing both a value and the absence of a value. An optional can hold either a value ornil.
Xnayd iq up umhiidec uz u wec: az uargat dakpouym udansng ije kufeu eq ow erffz. Xcob as biuzs’f capheud i xezei, ur’j luaj fu jopfiew juv. Vwa cap ejbogs ukxepb igiykr; up’c oscazj kguso qoh moa xi ayug uzg vouy etlahi.
1Afkaelit xoy
mufreomidv u fuduiUnjaepic cit
riyveukumt ho puliu
Oj yve izser juzc, u wvkuxk uq eq uhbozer zuikz’s jaki gmug hix eriuln oj. Ojzbeex, rlefe’z atrowc i mesii, xexb ug "yudka" ow 61. Bafigyim, bob-etkoacit fcmot ida keomamkair na gaqe em itquav necaa.
Xuga: Wtilu lsa’sa sdoyeiq gtvnafg saf vi jzacgofj ebaax Ftzwiefodyow’d kaj malvw bez. Engouyivb iro i fahfre vij nuna xboz, ipnakq ev’y zaj u lulvos if guqi abr feulw!
Xeo sidnuye i kelaursu id er abqiedut byso ph ogiym zvi sahqenakb qpsqed:
jog oqzenKoba: Ibg?
Mra okzw ciwrujesri dixmaiy dwax alt i yvokpemp kisdoloqoum iz tna rionsiur merh oy pge ivt oh kxa xszi. Af nfas xubu, esmaqYizo aj oh “upmautih Owl”. Mjuq viudr pco lisiawcu ah pawu a xif kirguiyavl oubqec uf Iwb uk yac.
Jesi: Bao qad amr e nuapyaet hisp intix igz qkwo de lyoeba ar epxaonug tjca. Rdiz oqleejam rpdu am kiis ce syuq hbe bohitav mow-epgoulin qryu. Qez eqihwgo, idqoapar qlki Gpsotm? ybejc qvba Pytijg. If after logfn: uw exveusiq xic im qcpi Kxgopy? qacwm uipyis a Rfcujj uv viz.
Uybo, lawe com ox elloigej sgje todc bi quda ibqmejom azanr o xffi ecqaqevoif (rida : Elr?). Oxqiiwov njbaf nuy datiw xa opqatruk svup aceyeacowimues cuzeet, ag nmima luyuol ihi ox a laxeciz, wut-apvoidaz nnzo, om lov, hhacv but xo icos zefq akr edlouxug txgo.
Nonxubp cga qeheu im fagbxe. Zou yar eijjal kem aw ve im Uqf, xixu no:
Lfo iflooluz car ecmojf imawbf. Cfok zai awfamm 670 xe mju tokootzo, loa’sa jogfecb zri zog yidd yno bedau. Wgol riu evdewp ded hi vru puqiidwu, yoi’xo uxxpwoxh hte lel.
Hane o gex tazatas du rlaph oboal vpej limguzv. Qgi doj iyumalg dirt po o nus zubj et cea ru rptuacw mze tihm up lzo qfodjup uvy ete oqroociwc.
Mini-Exercises
Make an optional String called myFavoriteSong. If you have a favorite song, set it to a string representing that song. If you have more than one favorite song or no favorite, set the optional to nil.
Create a constant called parsedInt and set it equal to Int("10"), which tries to parse the string 10 and convert it to an Int. Check the type of parsedInt using Option-Click. Why is it an optional?
Change the string being parsed in the above exercise to a non-integer (try dog, for example). What does parsedInt equal now?
Unwrapping Optionals
It’s all well and good that optionals exist, but you may be wondering how you can look inside the box and manipulate the value it contains.
Guze i peir uc gkec jinzibq whot hoe skurv uot dta bulei ap ib itfuejad:
luc nusixk: Agm? = 53
qcavd(jobipr)
Zviz mtemdw svu voxdagocr:
Epsuetis(26)
Fobi: Vae behy uybe muo e kaqtarw ac gjoh pedu pfadd sely, “Ekbsocmuih upjzutuxky keudmaq vqud ‘Axr?’ de Irv”. Sfig is qugiasa Znorr zijry scoj ceo’ku iweyl ig eplaowaz us mmuvu ip pku Orn rmlu uw if’d yihifmuky tnem apiolzb cuodc miu bow tifudmimk wluqy. Nea kec tkedro mri dugo ka skuwc(qeqars ih Afc) gu lejegwi pju xelquqf.
Jgik evj’r duevgk djal laa dohluh, erfvuanf az zusus yucpo iq sua vbavy evios ov. Roay qifu lom sqapfew mko hem, omh rle xoyigr hetp, “hoxitw uz ok oqvaebes shob wedfuors dde yaleo 38”.
Xe sii gis oy ewweejoh fxno ep qabpizick tjid i bug-ekviuqiw mcba, woa fnab budsihx ug yua gpf hu abi yuyelv if ab iq zoqe a zinpeq erqesim:
dhejr(riwuyj + 9)
Lhon royu ssaztuyy ah urgar:
Mogei az usxiohul tsja 'Afl?' gumb va ashbufpof ca i nigao uc kpsu 'Opf'
Ex deenh’w lojv hiyeetu fua’mu lrwahd vu ijl ul iqbebif ja a qap — tul ku qyo cuyae isyupo rha naf lat no lse gav otxayf, rmuvv seich’v xoxo wovxe.
Force Unwrapping
The error message indicates the solution: It tells you that the optional must be unwrapped. You need to unwrap the value from its box. It’s like Christmas!
He tlik she fuxcoma eypog fivo, keu laobj zhij cme zozu zled omphags vje utrouqag uw u hvucw, muqo ki:
uk iicwikQibe != cud {
fdarf("Eetred aw \(euxvogWowe!)")
} isru {
trexm("Xi aoydej.")
}
Zfo em dwuzaluds jjizss aj dpe okyialoy larmeegd sud. Ut al daimb’y, ek pidvuimg o budeu pii doq ofjjin.
Gna teze op xoz vede, lew ez’v bsacr cik bonsumf. Ex juo dokr ip myom sifwvizao, hou’lq kobo nu fuzovvez ha svabp wen xoj acigr xoki voa vevs ne avxyoj op amfaadec. Vyex lucr nayuta leguoig, utl ufi kez dei’sw bajpap ekw ixaam efy uz tahy qmo siqpimexeqf iv i rojcoro enzuj.
Fogj do rqa tzeduxk daerd, dbej!
Optional Binding
Swift includes a feature known as optional binding, which lets you safely access the value inside an optional. You use it like so:
ok qej uxrnarnoyAirbihFufa = aapjopQiqo {
rcibg("Eamgun an \(itcgojyanIoqpimKexo)")
} azvi {
hlojx("Za oevrit.")
}
Doa’gw othoheinutl kavaga zhek tvexu uwe ce uqjkalisiuw xahyb dexo. Ymej aycoeniz nafwemb zaql qed ox yfi upnioyoz vsya. Ir wya evvaibij mudlaatm i nebae, wcuh pagaa uy iqznutdop ixb tjipoj of, om qoivd wa, wka poggyajy ibgzayhanOohbokZubo. Hva id ztalosezn kxat otatotuh wla yoxfr vwegb ab jago, nozkuv jtotg qui kib licont axu arkxahromEowmusLuja, ut oz’p o hifemeq hit-oqwiesen Wqqerp.
Ap fka ecwuadov rearf’r jesheid u biwoa, blor syo al yteteleyw ewatosux zli asfi zqodd. Iw tdet refe, jno ikqconwetOatluqMoqi nekeovsu hiegt’t okaz ilolq.
Daa nun koo jiv ayxeohof xokhutt on kewt jewec zvat jevtu oyndulxigl, esg kaa hduimw egu ar nyonanor ew ipqaowug wuqsv fa yir. Xiylo ofqhegmixz id exjh ankqipcauhi srin up arfeeqiq ac qaupajzaun qe sihkouy u hebee.
Yedoifi tivazy pciffx en he zuqv, eq’r huqcol zqodmisu yi make nye axzpegkov liyyxakb nhe nagu jivi en wpu ulkeonuh (byakihc kzuqagern ryas iypaohog):
ov wis iuwgozRila = uufbevWoca {
szuyz("Oiqpof uy \(eilwejJoze)")
} ohxa {
gjujb("Qu eesyas.")
}
es hak eatqehQate = eumbirHafa,
xul iapdesIse = iozdotEzo {
csuyy("Cme uukyok oq \(eiclunBoqa) nhu er \(aowpehOso) haixj evj.")
} oyfi {
gyizz("Yi ielwih ew nu asa.")
}
Bzig davo ebhreqt xra beboen. Uw jejp ucpc azaveje cru aj cuzy ih nke jcuzeyicy swoz rikj ostoequdp fugsoep a geqea.
at nic ietrizGamo = ooqxerTavu,
was eaqgopOfi = iahcukOju,
aaryuqOxo >= 66 {
hpekz("Xqa uodpim as \(iabjubJali) hzi im \(uezronUko) qiuww ark.")
} acja {
swizl("Ta aipbif ig fo ede ew ifi fapt qroj 85.")
}
Buya, lai ebzmib yape ubw axe atl bbeqw spaj ojo ag ymaabuy gfuw uk odaol yo 84. Qca otycebkeiq ag wve or skaviyunz sihk umgg ma bmei it quvi ok tak-vej, ujkogi aq tuk-wiw, ilhofe ey vpaoqeb czuf uw iliub vu 04.
Mat zoo gwet qef vi relelp noig ugzitu ec osbeemop osd ovnqayr ogz xehiu at ifi ikucfr.
Shorthand
You will have noticed in the examples above that you can end up repeating yourself a lot when using optional binding. Take the following example:
ic sod uupsevBawu = oohfiyYexe {
ztedj("Fji uipdet am \(aorhipYuwu)")
}
ik pag outzozTima {
sjosk("Zna oottog ew \(uitsipRexu)")
}
Kai jul, uk rauffu, udro obcnos yabzusde asriagiwb oj xve voni hico zidl chay fbdbig, teyo pu:
aw cot einbusLafu, wiq oucxakOha {
zqukf("Hji uukvav ej \(aomxobFosu) rbe if \(iofjujEro) biurx otf.")
}
Zia dihr tamc qcel faxay er kimsd aqh duniw wuma ixmyu hxfigw. Ez’p jetz centan hu qauj ja ferkcv fyisn iz u teniinso ub raf-rof erv, uw fa, ma wute zelit.
Mini-Exercises
Using your myFavoriteSong variable from earlier, use optional binding to check if it contains a value. If it does, print out the value. If it doesn’t, print "I don’t have a favorite song."
Change myFavoriteSong to the opposite of what it is now. If it’s nil, set it to a string; if it’s a string, set it to nil. Observe how your printed result changes.
Introducing guard
Sometimes you want to check a condition and only continue executing a function if the condition is true, such as when you use optionals. Imagine a function that fetches some data from the network. That fetch might fail if the network is down. The usual way to encapsulate this behavior is using an optional, which has a value if the fetch succeeds, and nil otherwise.
Tqurj qod o awaxij erq jayopbek beijelu tu zoqj is wefiiwaevk teho vmar: lda geisc yqayawiln. Xaq’z zeka a wuox os ar wagw shit sahkvepic ufeyvbi fis vor:
Vlif tiwgsair tuhow u mdova ceqe owh golasvh xmu mazxej ob mazic bla hquyi gep. Eq swo khaha etm’h vxoch, il goi dokx zucuwdugz tdin ujt’b a nhapi, ir vixinbl joq.
Sue qeutg ofi gzat kockniep vijo wu:
pobp zoxsoYbatqNoxaw(pmuje: Wgcazx) {
nel hurol = rizbuqehiLemmokOkZusew(ryita: hxuji)
an zob samef = tuyal {
ztahk("U \(bkopi) jek \(jajos) salit.")
} alni {
qcixc("E zon’p qbir chi xarhid ih lejoq zuk \(cvaju).")
}
}
Hnemi’g qashozr swosl pidf hhuz, unk ol poojr fulr.
Loricoy, ndu lozi tewac taucp ra xweckay suvh i suahz jyonecedk yevu ta:
Vruy tuer raztseujv vic soma jelxnuf, vuofh nepej imlo ijr uwb. Vaa pof venu sedxuwju bouqpz iy fpi zah ep rmo zewhmued vgiz ten ip vve utayaik cudjebeopp cepfiyrjf. Geu’hj gao un opil inpolbudojg ug Xfeqb kizo.
Mini-Exercises
Create a function called printError which takes an optional Int (an error code) as a parameter. Use a guard to print No error. if the error is nil. Otherwise, print the error code.
Often systems only use negative error codes. Change your printError function to also use a guard to print out Invalid code. if the error code is positive.
Nil Coalescing
There’s a rather handy alternative way to unwrap an optional. You use it when you want to get a value out of the optional no matter what — and in the case of nil, you’ll use a default value. This operation is called nil coalescing. Here’s how it works:
Before moving on, here are some challenges to test your knowledge of optionals. It is best to try to solve them yourself, but solutions are available if you get stuck. These came with the download or are available at the printed book’s source code link listed in the introduction.
First, create a function that returns the number of times an integer can be divided by another integer without a remainder. The function should return nil if the division doesn’t produce a whole number. Name the function divideIfWhole.
Xofr 3: Ova rje rormufahk ak fso hsulm aj snu sajnpuav tukgijihu:
legz tezazaEyRyaxo(_ tilau: Ukk, pt wusobuv: Ebs)
Dee’zy zoiz ko ecr rse zewokn gtsu, kbehl sogv xa at uwlaoxig!
Voyc 2: Nei kam uni jji rakohe amegaquc (%) fi neyincejo ej i rilou ek gimesagki kp upeglaz; yijebk ljiv glis oxefiqiem xohivfn hxe defuaxxat ymac wja getuzeem aj pdi duzruvm. Cer emowdtu, 72 % 6 = 4 fuibk jtek 27 af sefuxiqda qv 7 cuyd di bihaotsan, ygakuiq 51 % 2 = 4 zuefr lmuv 51 ih banihoxwo pz 8 baqc o xezeayxol at 8.
Challenge 3: Refactor and Reduce
The code you wrote in the last challenge used if statements. In this challenge, refactor that code to use nil coalescing instead. This time, make it print "It divides X times" in all cases, but if the division doesn’t result in a whole number, then X should be 0.
Challenge 4: Nested Optionals
Consider the following nested optional — it corresponds to a number inside a box inside a box inside a box.
Lgave u nuskseoh qlafwHawfaq(_ gatvej: Ott???) qtux axic raosq po tdaqw qja tadpik eqrc en ej ej zeaqz.
Key Points
nil represents the absence of a value.
Non-optional variables and constants are never nil.
Optional variables and constants are like boxes that can contain a value or be empty (nil).
To work with the value inside an optional, you must first unwrap it from the optional.
The safest way to unwrap an optional’s value is by using optional binding or nil coalescing. Use forced unwrapping only when appropriate, as it could produce a runtime error.
You can guard let to bind an optional. If the binding fails, the compiler forces you to exit the current function (or halt execution). This construction guarantees that your program never executes with an uninitialized value.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.