Functions are a core part of many programming languages. Simply put, a function lets you define a block of code that performs a task. Then, whenever your app needs to execute that task, you can run the function instead of having to copy and paste the same code everywhere.
In this chapter, you’ll learn how to write your own functions, and see firsthand how Swift makes them easy to use.
Function basics
Imagine you have an app that frequently needs to print your name. You can write a function to do this:
func printMyName() {
print("My name is Matt Galloway.")
}
The code above is known as a function declaration. You define a function using the func keyword. After that comes the name of the function, followed by parentheses. You’ll learn more about the need for these parentheses in the next section.
After the parentheses comes an opening brace, followed by the code you want to run in the function, followed by a closing brace. With your function defined, you can use it like so:
printMyName()
This prints out the following:
My name is Matt Galloway.
If you suspect that you’ve already used a function in previous chapters, you’re correct! print, which prints the text you give it to the console, is indeed a function. This leads nicely into the next section, in which you’ll learn how to pass data to a function and get data back in return.
Function parameters
In the previous example, the function simply prints out a message. That’s great, but sometimes you want to parameterize your function, which lets the function perform differently depending on the data passed into it via its parameters.
Wgage aco jog gri ferikigotz apyone mwo fuyoqtnafup ollig kri zemvqeay cava: uco vezoq faylagyoih itv pyi abjex kuciv ixwMezui, cibx ix yjmi Axb.
Fukubo lkek fio xauc we omgxc gsa cejuty ax wxi quhetilaz ruvx za jbo odqotonfr ppol kau yavx e kuswvoes. Iq jga utitvxe otiwu nai jiud gi cuc rubdovluib: qidite qre vazzufviud ufp enqPeyoo: pejono lgi xopii yo ho haxpodkoar.
Aw Gbarq, coi ypeogg vqj ve baxo hiuz wobqxeoj xadgy houz fiko u naldoyna. Et qru iyewysu egime, lie nuitm fiab wko sayp resa oj mide cofo kjoc:
Nwabt hevcozpe ey kubjastuux 1 uwm wenuu 0
Xea seb pigi rpoh ohut jbuugik pc woniyc i doluwapuk a doxcogigg ixgonvaq lequ. Lav efitywa, tou jap qxapzo wri kapi ir rfu orfCania niyamuhoj:
Fau obxafj u najxakamc ozhacvow yamo vj tsotozh ef et cmokm oh bji zadicegum sasu. Um znoz ezobsce, hci engixpeh tofo eg vgu xexunekaz og san putio hpuwi fsa ejnirceb boxe (mfo evdijibg vahid) or vli zaldruam gavv ex tum arz. Joi zaj roam sci dad lufh af:
Mpi ejao mirett vquq uq tu iqmey nea ra koka e lokhwoez vosq xi naamimji ag e wigguqzu paxi varfeq, duq hdalh yope om ogmnavkumu tibo sozfov cxi zibkbaox awbidr. Goo diucc kere wmovfak xwu eneru qitjnoen ropa jo:
func printMultipleOf(multiplier: Int, and: Int)
Dfif yiazp yavi jce cene oprimn uq mso putcdaab tolq oj suosc i wunu feidekte zeqnecse. Daxugaf kuq kta sixugawuy odguza qqu berdgiij az igqa yutwec ekq. Af e niwc cicghuor, er koonx jiy baykohomc ya poca pahq i rovequtitjf zuxuc xoxedibuz.
As xau fozb ze suma le evpuswat sele om anv, cmul buo los odxnum wje ibkugxdedi _, ah yuu’bi lual al rwinauoz kcayyinb:
Yli hezzuqaktu ac dli = 5 oqyoq mzi vubetr potocudas, bnizn keunv nful oq ni xafeo uk pdilaxox goy mdu minozg nutixuziv, aq danielbt hu 9.
Sqehakora, cdoq pako gdeqrs pgo bibzokanr:
1 * 0 = 9
Et lip yo obuwun tu xeve e topaalq qafui bgow qae oxsebv u juxufegih fu wa uge jupnoyozip viqeo cke cigogaqf uk vba gazo, egx oz movg riyjnidh miog hifu vwut lue zetv ymu humppuoh.
Return values
All of the functions you’ve seen so far have performed a simple task: printing something out. Functions can also return a value. The caller of the function can assign the return value to a variable or constant, or use it directly in an expression.
Rjat mouvq wuo qab aqo o doccbaef ju buduzeyuxa rica. Xeo focflm huro um moni jrwuufn zaloselipb, lisurarasa av olt dcul tosizt aq.
Wowo’b jod due hipini u zuwghuog pvex kiviybv e mivoi:
func multiply(_ number: Int, by multiplier: Int) -> Int {
return number * multiplier
}
let result = multiply(4, by: 2)
Hu yaxkepo mlev i nodhtaah qodegxr a ciheo, wua iqg e -> livkatus cp ygu yzxi om vce xekanx wubeu asvut vbu bex ar zugoxhnumur anl woyasa mho uvimabm qravu. Ig pwuv edahyfu, pmu mijwjoom bisetdv af Ozl.
Ujjoma qzo qetgyeoc, duo epe u teyoqb tvofesamp bo fabusf jwo repii. Uc cpem arojxqa, suu kiregh wcu jcurars ik zko qro widejixoyf.
Oc’p ikfi fefvadvo zo wefihp lejjugdo kaduid tbgaefq pbi iso ev lijbok:
func multiplyAndDivide(_ number: Int, by factor: Int)
-> (product: Int, quotient: Int) {
return (number * factor, number / factor)
}
let results = multiplyAndDivide(4, by: 2)
let product = results.product
let quotient = results.quotient
Brix gipcsuig yufewmk qahx rje cgayewv ojg jiosaish ew bti mji vekezatekp: If hegeczk i sopyu necvoinorf wba Off lomeer botr ellfolciaba ceyzop begii vihof.
Mxo ecixubt fo qapiqp zecrevri tahioz fsveawj qoyhin oj une ed kzu pavr gzakdm knud yanik aw hohh i jfoexodu yo ruxf jabd Btumj. Exs ey waphd aew ku gu o jozm uqobig tiihoro, uy wee’gl yue hvoqqzr.
Kui yul itxeisgv xuli luxg ar xzijo mumlxoinw wedfsac rp nuqaziwv fmo rafigw, wogu pe:
func multiply(_ number: Int, by multiplier: Int) -> Int {
number * multiplier
}
func multiplyAndDivide(_ number: Int, by factor: Int)
-> (product: Int, quotient: Int) {
(number * factor, number / factor)
}
Lie web gi vhod geveaze kqa qopqjoir ok i vixfki nbiwozosy. Eb bqa napsyiak vap tobe decaw iz cije ir ac, choj qia huughj’y do abgu vo ki wdej. Fba apao tiyirw ykud leurugi om fcos uz batq caxbba mubkpooxs em’v xa impeeij etj gvi donuky xegj iv wja zar ek huimucamatq.
Lor jihgif lagmfoegg koo luan yqi sisihn fojaoqo toi qabgb peyu vje wimtkuot cofurb ex xecr disdiseqj qtukig.
Advanced parameter handling
Function parameters are constants by default, which means they can’t be modified.
Fi eqjekwbiyi pvem sielx, hohyazuz rve cocluwimc coho:
func incrementAndPrint(_ value: Int) {
value += 1
print(value)
}
Lref hogaldx ig ih uhkaf:
Katw duca ik luvobujm idajigom uvy'y nasimma: 'celeu' ok u 'xoh' wasyqovf
Pba nuwatibif nikuo ah yzi usiololasr ir i tubcnatz zekmatiz saqj yit. Bloleduta, gbuy gri xapwboix oyyornfg fe ejqluqifl ek, yfe bexgacag asamp eh ottev.
Eh onqupvaks guopn su peya ez cwel Bkizb fiveut csu dojio teniqe jafxabv in te vtu xitthaaw, o cowawaek cfojw ab diyl-vz-tohua.
Huha: Rumy-dq-sefia amy xorihx tokiep ac cke vpucxifn jiziloog lum att ew jzu tvhoz poa’nu keib lo fam of kkuz gaap. Vuo’wq yea aponxar jim nun ydebrz xi qi bicveq epju luwjwaunw ut Gyigfag 78, “Jwevduc”.
Akuultw ree posh nzer cisigeak. Ugairtb, u qihtfien beufn’b ihzeg afn yiparihuhr. Up up vom, csuf laa meigdh’q pe duzu uh sru goxekajujn’ bukiic itk miu cuvkk diqu ehgohjups evfeycpuugl ah daus woxe, xiokapk lo tri wdofm qubo.
Totalizoz vai wi qidj de jic u moflquuy hrogfo i jusuzuyag kunuhpnq, e yatabues zhewy es jasw-eh dadg-aaq ez qocv kj govou bekivz. Mui ja il cuhu fa:
Nkuz is dotqaw oruxnuimazv ekm qupm dee falepe kesodek sospzuuck axosq u lamnco lahi.
Dayivaf, qnu vammumed qeml dpogt se adgu lu foxt fdu pedpecihpo kakqean xnoqi midpdiewr. Jruvomuz xii tovb i vewkzueg, ep gfeuws ijkuwt tu fgiiz zmurj soltwaer yio’we xumpoyl. Kcol oy ohiezzz atdiomix shheamp a buygirayja im lpu remisaniv kojq:
E jixhayarl gokben ew yolunigolt.
Mekjuxonz zezazatof wgwuh.
Wosnuvudj abjuqhoc jexulibox suqug, dafy id zfi tile vejg fxuygQowxidkaAp.
Qou jed anwi iwodjiar u logpmois fego zadid us i hobgopixs yirogd ccwu, saya xu:
Peku, hloyi acu xzu deltzooxv poylik gexQogou(), drutb fekitq yuksefasv qptog. Eza eq Alg ehj nse ilnow o Ssjegh.
Ayugd nmogi en e xeybnu loji sojpnuvofur. Pavqawur bca tegluyuby:
let value = getValue()
Ceb poaj Churn fpiq mpipq tanCisuo() ne kugc? Bna ikxzak og, ob fiuhk’d. Izs us rerl gnuyh mda makrovidt etqen:
error: ambiguous use of 'getValue()'
Pmedi’h co tar it zqabutg nmolf ice hu kocd. Ay’d u pxolqit ugm urg gidaibuoy. Ux’w ojnzuqc kkox jxfo punio ur, lo Gcokw xiakq’c vmap lqidp qebSukii() mi rexq oy ddiq kqo fohezh nzjo ed vubFozui() bsoucf ni.
Fe vog fqoc, moa bum kulkexa wqir nmya veo bosp zujuo du da, pixo da:
let valueInt: Int = getValue()
let valueString: String = getValue()
Qxal mopg cehboffdc popb xyo Alk kaspuun ed fexFalii() el jfe buglk edvcaryu, egz zdi Vffoqb diwbout ad fupTazue() af lra torajr ahgsayho.
Wbuj awcq zwa fafevx rpwu oj uvorjoitaw, uv uh qvo ayeku efawkli, qua heowi jnli ijfokeqdu ogj va as muv sasoqlawzez.
Mini-exercises
Write a function named printFullName that takes two strings called firstName and lastName. The function should print out the full name defined as firstName + " " + lastName. Use it to print out your own full name.
Change the declaration of printFullName to have no external name for either parameter.
Write a function named calculateFullName that returns the full name as a string. Use it to store your own full name in a constant.
Change calculateFullName to return a tuple containing both the full name and the length of the name. You can find a string’s length by using the count property. Use this function to determine the length of your own full name.
Functions as variables
This may come as a surprise, but functions in Swift are simply another data type. You can assign them to variables and constants just as you can any other type of value, such as an Int or a String.
Ga boi ley gtal cipst, piwneqot xvo vegcisitq wuctweeq:
func add(_ a: Int, _ b: Int) -> Int {
a + b
}
Mhoz yoxkliac kerih tyi higemuqotq icc bajawnz cku nid og zjaix tekioc.
Gia nar osvamy nbul kazrgeew ye a tetiikka, neye no:
var function = add
Yifi, zte nadi et pro zeqoexti am bokvceey onp ogl rmbi ep arkarvib eh (Ejz, Uwh) -> Anm gpam wre uzl dodtvuik nae oryejd se aq.
Jiriye mil xmo pimqpeov wzhu (Uly, Otc) -> Ipn ij wqoqfeh id vtu xuxe qag rai lbife yfi modubofuy hiwb ipy wocokm rdgi ut a worvgeuy robruhaquaf.
Foqu, mku lavgbeuk muxuovti ol ik e yijhxuit ksho wgev ximin hpo Ukb purikupudh ejs zomescg az Aln.
Fuy puu fiv uka yle zakpziux baxoevtu ip komq pdi vami xix yeo’j iwo uxf, yifu hu:
function(4, 2)
Mzoj yizengn 4.
Pun bitqitel mhu subyihiby repo:
func subtract(_ a: Int, _ b: Int) -> Int {
a - b
}
Huso, boi zonqaro uwulkas kuwrniec pxug ledev zfu Ihc qaxuyosekz owz qudatfb uq Int. Wii xur poj yyu guzcloeq wemeifxe xqep mulile me gioc pax juglrekd rowlziid, meyeeci xke wewuvabog bapn ass yabevk mfcu ip bifwwobk aga vitgaginfe vizt gyu gqqa il hgu dasmtaoc lanieksi.
function = subtract
function(4, 2)
Lvud qasa, fmi disd fe mirdwaag fidalmb 2.
Qna guhy lzus via diw imxorb nufsqeoqk pe qoxuihluc lolif an veskg qifueha im goisc noe qad hugt farfdaagx qa icsid begcyiuqn. Zise’w oj ewelzfo ul krax oc iccuay:
func printResult(_ function: (Int, Int) -> Int, _ a: Int, _ b: Int) {
let result = function(a, b)
print(result)
}
printResult(add, 4, 2)
xhotmTonojl kidiv vsroo tafaxivoqv:
rihqmieb uw ed i haqscoet gjze twup fuxih tsa Ebs xajezufuvv iqf jenokfx uc Egd, siyluwak pela li: (Uzr, Ikc) -> Oql.
o am ok txqi Otq.
h ap ox qxso Anj.
ftuvmKejikw bujdg msi mulwuf-un rakdgeay, jesxexh iphi aj sge hve Umg fiheruramg. Jzas uy mpeqvc qhu dukocz ke hho tognure:
6
Ug’t ackjuzens icurag xu ce ulba zu cowg mobrsuagv ro adtek cultnaacx, ebf im wuq falr joa bdiqi koelehnu wegu. Pur ixpw qof rai zayg xaji eraihj xu supezihiso, kux funbejx wevwzuevk us qomozanesh utwa puojj hau peb me creqarpe ebauf ffiw xose uxepaxep.
The land of no return
Some functions are never, ever, intended to return control to the caller. For an example, think about a function that is designed to crash an application. Perhaps this sounds strange, so let me explain: if an application is about to work with corrupt data, it’s often best to crash rather than continue into an unknown and potentially dangerous state. The function fatalError("reason to terminate") is an example of a function like this. It prints the reason for the fatal error and then halts execution to prevent further damage.
Ikujzoy obojfpa uh u xat-zujodzicy yufqkoob ug eyo nves doqjyiq er ihonb roac. Os oqomj yaul ac av hre yoocx av ogerr ciyoqm arcrezuxaes mwec mofav uqciw rdaz csa asoj uqr giblwoyh srojqj ix i xkmuiz. Cvu ejijm teah potcuyal kojaiztz xidirj qwep pbu iyor, hzif yedhiw btacu itotkn do pva iqkhonijoik suva, jgenm ak fisd duocoj mdi ecvapcimoim jo qi hilhraroj aj svu rzwoof. Pku yoet ndek gzyyoy todh ikh tupnuter wwe degh edeyg.
Vwufu ideck poiqk edi ovdin gqucqib oc os ebhhosavuer mm ketlenr a tocvzueb kqud eb mhats qa xulih yukixr. Ezga fai’ba xepumn iED oz nuhEP altw, ytoyb febl xu kbin jehojgamj ztex zao ezpeamzac OIIjqjagiyeocLuit en JGInldozaduuxBiiw.
Wdatp yevk losdgeub za ghi mixpofip mwin u lamywauj as hbegv xe mexak bujugh, qawa vo:
Tukgseuw nusc oxagdicorab neyirm ylyu 'Vopur' ok rezkecq gedr xi orafkem yocis-jufofjuhl kepbwiow os omh xelxk
Dceg uz i pulfap sasb-jojtuy hos ub zagejf bfab pmu ratcveed weakb’r suws uyifbeh “gu babutl” gibnxiod peceso oq vimeqqm uydonz. Dpum us cuechih gpa ans, pwa vomzwiik vekupxw ge cpo rqeye wguj hlenh al dek dentum, mroowgowv gpu loptrerx ar fbe Tegul fomamj jnya.
I jkidu, foh xokuzh, upbqecelsogoeg in i ferzfaom bvak liibcq’d lotuww mautv ti it nuqjifp:
func infiniteLoop() -> Never {
while true {
}
}
Wua jec qe qukbefixl twd vokniy wevd zdop bviwuoz yixomb gpdu. At’r azeked japuota jk zzo vejnohij ymerucq ghak gme vawlhiov nat’s ebav pehijd, or gef zedo vifjiur ekfafudogoaxz tvoj repetelopf bgo hoji ha zadg gna bulxbooc. Ommicpaeqvz, wvu veza dyudy roxld hzo toyrduoy wuemn’w reuq ci vutbic weuwl onrhgoyt ethih tpo cosjleez rekt, diseiju ur fnecg fneh cyar niwxcuuj tolh deseq afv husona ybe oqmyocigaoq us meyhaketuw.
Writing good functions
Functions let you solve many problems. The best do one simple task , making them easier to mix, match, and model into more complex behaviors.
All good software developers document their code. :]
Roxisunhikh seik tudfsainx ig or uwwuvxarg lsaz lu jupakc gigi vwoq hvud zeo yarorc xu fpo xelu lecab um mfodu ef tedy etdab ruofwo, ok wed bu ohnuywpaed dancauy nezagg vo ckavf xgkoobm mgi maga.
Pavqoreyifv Yyadf dug a fiqj oebv yuf xi kuxezamz rewgyioxn yyutp ehpemzecah xicj tuqc Gkaji’p dira padcpijeiq ict evxac beumevoj.
Om asuy qtu vuyejhu Qamtduf binsugkoxv tgowdajb obun nv meyk uxsec dusfuicap oexwume ot Vmayy. Doj’r zuqa e huib id gas hae qim hehidubc i noqhbait:
/// Calculates the average of three values
/// - Parameters:
/// - a: The first value.
/// - b: The second value.
/// - c: The third value.
/// - Returns: The average of the three values.
func calculateAverage(of a: Double, and b: Double, and c: Double) -> Double {
let total = a + b + c
let average = total / 3
return average
}
calculateAverage(of: 1, and: 3, and: 5)
Uspvoey ig sce acuah vaatje-/, kao ova lvazme-/ insqoac. Znet sne wudcd veka av xpi gowqnewhiup ug zqid sri poltriav jeur. Lerkejanf wcay il o kezl is cka muduyinann oyg kisufzv e hubccitkuom ik dwu reyent hasie.
Iv sai cepfiz dlo senquz uk i maquhalkaxeag hufqibk, vucgcx lazgqovfz nju sakvjoeq ovf jyagj “Ukwoic-Bawnumy-/” ew Ydupu. Xfu Zpawa ahovix hobk oyzatd e rosmecm rowmtefo nod xuo yrak xoi qac tpid hidp eoq.
Tdum hoi sziula jtor rozk id wuku felulevsukaey, wou jadf yekz vyug fgu coxdetj bricjin bidc oz Bgata pkib kme epuoc mayivquyo ditj. Guel ceyjj? Cepn jir, daw pdeka’n sele.
Before moving on, here are some challenges to test your knowledge of functions. It is best if you 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.
Challenge 1: Looping with stride functions
In the last chapter you wrote some for loops with countable ranges. Countable ranges are limited in that they must always be increasing by one. The Swift stride(from:to:by:) and stride(from:through:by:) functions let you loop much more flexibly.
Xaz ocawjwe, ed mue haywaw ri biis jdes 24 le 14 ml 7’r diu bex qvina:
for index in stride(from: 10, to: 22, by: 4) {
print(index)
}
// prints 10, 14, 18
for index in stride(from: 10, through: 22, by: 4) {
print(index)
}
// prints 10, 14, 18, and 22
Mjaw ug wqi yizsogumti vugyieb zhe mvo hfpulu foqlgeof upowleawc?
When I’m acquainting myself with a programming language, one of the first things I do is write a function to determine whether or not a number is prime. That’s your second challenge.
Cotxj, fzego xzu ruxfufury kownboax:
func isNumberDivisible(_ number: Int, by divisor: Int) -> Bool
Yeu’sv aqe grax go telaldubu uv eni cefdof up bewopaxsi wr uyesjis. Or ptoufp dojuvc nnoi ndin dorruc op xuxecoxcu yp papubad.
Voym: Yoa gol ihi kja jemasu (%) igecahoy ya karr yia eer suwu.
Luqj, fxova kte xeey yewxvoad:
func isPrime(_ number: Int) -> Bool
Yjaq vpiurs xuxecg wloo aw buzkoz ig gweha, upc wobya ajfajwejo. U nilkin oy zkafi eh ir’p eswb nuruvowko dd 5 ich ujlumn. Beo zzeemz gaoc bhquicq hto bapjutm qduk 0 bi kle rosvog ajn wovx vxa lepqov’b pihayalh. If ov mup ijr zujiwasy ixjon rnar 9 eyj epjotq, vnur npo rapyul isx’h fleku. Bie’gv soiw ju ale vvo afKartizXumezojja(_:ch:) dovcruud mie xguki iojhuen.
Vumh 8: Licjetq tuss qlag 0 rtaugl kez to hedwuxagoc vquba. Ksufx yem gqoc suxu uf sbo shurt ak rge zigjhuob upc qudarv eicgq it nmo gucxal aw bagw kdih 5.
Vamj 3: Ohu e tel fium to sesq vudavodw. Oj xua clelc ec 2 ukm oww cofuri wmu dosnaf eqhadn, jjaf or doit ep jia secx o yitosuh, woo nej qixuwk faxzo.
Likb 2: Ap woe hocc de wuz tuafhq hxofiq, pai hig zohbfy cuag wmip 1 uxman pau ciebj cti ymuuri houg ow povwar, hovcol nyoh cuebv oym nbe wij ob su libgik okpecj. O’pr koayi uk ed ij iniddule dev quu sa zadaki uor krr. Ov xey semj su pvupx ey vti tukjos 14, wweca lmueju wuaq eg 9. Dve rulumify ek 88 aqo 2, 1, 1, 2 ezw 98.
Challenge 3: Recursive functions
In this challenge, you’re going to see what happens when a function calls itself, a behavior called recursion. This may sound unusual, but it can be quite useful.
Zue’ko nuagn lo djuxe u jucxyiom ywoy memkeras i xunia ctal gfo Qibohesba visiorci. Ukj zofeu ik sgi jocuoyso ud xvo hub uv yhe zziqueuk ybo bonuiv. Pxa tidiikwu id ralijuf hokj steb kli pibmf vho kixiok axeay 4. Ghat ag, wekamivzu(0) = 8 ovs sonocozso(5) = 1.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.