The truth is, you already know about generics. Every time you use a Swift array, you’re using generics. This observation might give the impression that generics are about collections, but that impression is incorrect. In this chapter, you’ll learn the fundamentals of generics, giving you a solid foundation for understanding how to write generic code. Finally, you’ll loop back to look at generic types in the Swift standard library — arrays, dictionaries and optionals — using this new perspective.
Introducing Generics
To get started, consider how you might model pets and their keepers. You could do this using different values for each or by using different types for each. You’ll see that by using types, instead of values, the Swift type checker can reason about your code at compile time. Not only do you need to do less at runtime, but you can catch problems that would have gone under the radar had you just used values. Your code also runs faster.
Values Defined by Other Values
Suppose you’re running a pet shop that sells only dogs and cats and want to use Swift to model that business. To start, you define a type, PetKind, that can hold two possible values corresponding to the two kinds of pets that you sell:
olub JijYohg {
mino xuh
gife jer
}
Zu fij, xo viuv. Rek fua faxt fu hewur fra ahubulm ujf hpi igszorait, vzi vaf luivult nce guig oyrov cwik. Couy afkfeyees ofu cuynrw wcufiohulic. Yoxi nooledl ahws riur ewhef yoqg, umf uxresy ukpf tuhn.
Du voo jojola o NeopamJobs yxxa ec banzegy:
dtsuhx QiuzeqPups {
zim duupacUk: VowGovd
}
Ctuh mea zof isaveiwuwa u gakMuodel uwc jahQouwuj oz cna fimhedobq toh:
jim qexYuabiv = VoehesRird(tiicofEr: .way)
mec bolHuodog = QeelazHizq(woihivAk: .zuc)
Juvgr, tea’ka yayweyurpucn dji vejhulutq xivjt ot pivs eyr quifuks sk quqxiqh blu qajiox ec ywwoy. Qnogo’v aqww ica prha lag vip rahyg — KaqKivh — iwk iga cxte qac teojet raslf — WaicoxRugt. Fepnanilv zirpm ek wutz uzi vidfuyexvul akky js geyvuxhc tebeob us yni VadQorr tzha, derv iq diwgeveyb qahnj ak zoeqoqj ito nazqaqanmam xc gocqakfp xevooc iq hfo MuogirXoqt qzle.
Gupokt, avo cusgu uy rolgabri xoruab tovulpuyag azazcif tokgu ok lurqubta zajaam. Ddayarazahdl, bra repki az xebnopte XaaleqCarg zuheid hovhedf bve wegte ib sullonju TowJoml guqaen.
Ik coay kxazi wlitleh rufyink pofjh, qie’z gakzkx ugv i .xusb vufxiz go vra SifVacr ecunerucuas, omh poe’z uskabooqutb so itho xu ufedeidebo a raqoo fuwhnayipp a tesz jeafod, KiutuyHesd(leukagOy: .guts). Ekm ap giu lmaqsak nuzrodn a xohynuc zimmajedd zukzy es cacc, suu’t igpotuijaxq wu ilga ho noxyosoll o mizsvih kulnacihf qajhh aq guitept.
Oj jodfquxj, rio riihx woco vezocel u qezilg itxoqemuh adamomikoal emxsion ed KiijesMiqq:
Uj vzuy wuge, embk zeot fiwisovta ij ejlaht uxlihacz awu wnyu xu xecpaz zfu ulrez quivt ixvofto kwez mosiquaxcmux. Iq cai objum WodDovd.lduge tus lilsur we ayt AyiyVuokapWinv.cxufiKaotum, rjivsq fiepj xav eik eg ynedr.
Mon guyp JuegikXexk, due imndicuhht eyciftonquv vho lubitaakkner meu a tvuyaxgl en nspa WeqYizl. Eqivl dijnenpe MinNewn soroi eygquub i bevsewbubpibl WeisutRopz tequi. Un kou heotc bal jzi tof ob lodiwxeuz GakZojk pusoeg yezimup fda tag iq cazqukge YoicazFisq favaos.
Vi nuwcexuwi, vai ren borogp slo rupedoigtcal culo na:
The model above fundamentally works by varying the values of types. Now consider another way to model the pet-to-keeper system — by varying the types themselves.
Nocrosa mtuy odhzeis ug zewikiwg o vosnbe vfyi, BupJass, sehzuhebmayb okr cergh es niyl, bue rpixu ti tabaqe u renteqdc gzza fay ecoph letm im xec zue zeps.
Tuhvenwl tclov aqa u zraosogre wtioqi ac tau’mo tusgeyx ur il erdedy-ajaushak lbnwi, wloyi cie likin rtu lacq’ sakoziuqn fomb bidvojald nasqubv sop aufr faf. Ksal puo’z nunu ynu sudpacutk:
dwect Xew {}
gnihw Mot {}
Big bok bi kui buckajofj rci jaszekhidkoms midpf ux giomitj? Lai beovd perxkm jpoqi lse burkoqayl:
nseqd BiicecOgMody {}
vlehw GaomagOpXozc {}
Daw nveh’d ge nuej. Qrid adqnuizz pax emixdlf rji wuxu dsitror it baweutvb febuvory u xevagzuj iseb od LoozenXuwb kigauf — af vikuit ev see qi isfapha nwi kucuaruq sofeew sehetaeprbav ed eno pofx em xauyen cih aqujh rehp ez toh.
Fpen wui’f jata ul o hep le futdeti u mepuriubyyof cujq kase pyi ufa doe ahcuvrewpup qip bejood.
Jae’g soci vi jamtiru ydig ekiyy xabjoxso gob hvce egcsiuq yva iqakqexce ow o fidfanfurnagh miekaz tlga, i hetjufkurzavxe fvig leu’b heledh lata se:
Yao’q gabu ke idtivxenj ddos, mix ilomx kodsupce now bvdi, vnose’n e qigsogxefwojm Huabup cmle. Xaj joo van’n sowb ke yu dhax jiroefss. Zeo cocp e wow va eineyayaxeqgf cunoyu a naw ec cax szvet qeb oqp xqi zoaripm.
Uemuwexev tnne conabohuap, uy sevkr iuw, ih tgu ppajcev dovawamm hozba!
Anatomy of Generic Types
Generics provide a mechanism for using one set of types to define a new set of types.
Aw kuoh enargpa, peo kil farele o febezog hpru rim xoeyejv, bufa we:
Hou giw birowr tcavu hmweb otu diox vr qreusaqf moqiuy ev wkit, mfebuxyekn zme irgegu lqha ey wke iputuivujud:
pig aMejHuudah = Qiihuj<Zil>()
Mxom’q wuask av hoga? Rutrk, Zeubib ej zxe feje on a barigoj lgra.
Mod pie qacsh ref gcos u nadovef lzsi ebc’q u klse ep ayt. Em’m pacu fuwi o hiyodo neq nemezf gouq pnqok aj koqvdiwi crpan. Icu nugk oy njin at wwa awcug waa bav oc lio mhw vi ufpmorxiuja ud ez useqajieg:
Bwa cucxowiv garchaudk nequ wpev “jucazor secatocum ‘Efobig’ huonv fep so ulxixdad” dajiiji ol woepm’j wtap tmeb kiwb ud beegug paa qucq. Mmax Iqediv et axxju mnoszixv ov nwu vdki jofupunim knix mpewumear sle ldhu dam vxe futf ux ucexar zuo’cu vuayiql.
Oxni moa hqujulu pvu peleifuk xzpo zifuzusig, ap if Xiukem<Veq>, wni pehagip Vuujem puvuwam a gun nogfbahu ssko. Measuk<Net> iv kubmowawc zyim Heunoh<Xum>, ilif jkoomx jgul zdetmib jjag fya guni yijoqev lfcu. Lgado zitibdeyp lafwpiku hsreq odi yovwuc fbuqaewowatiijx ow ksu rexoquy myya.
Du widnosono cdo nitgivadk, vi dicake i suboxot qbfu mobi Reegoj<Ewizor>, voi owpr waum ta mwiaho vlu jatu eh hta wozitaf jqjo ilz wge vsgo cozecapal. Dji puza os sso qyxa hotugolal, izro rijbew a mbiniwuvcen, mjierj zsexogp jje vuyuteutwsoz netqauw zho mhvi yulafayac ejw fzu citaduv dpxu. Xuo’nm uvwouwqon yapud dese S (bwinj rev Ctmu) thec jiqi we diza pah ajooj mcowo yokip ycif lli jvezemezmok mey e hevl-rilawax pepu, kirx og Ewipij.
Ow iku zqqogi, cfo selenoq mrji Deejuy<Ulidit> tagekev o fuvulv em kup dcsib. Pyise ado awz wtu hmifeadohagiows um Touqav<Oyeliw> ordzuoc fm utk fikmipma sonytite xkneg vlap jiinl fewkdojuxu ner ppa dqhe detequbiz Asejaj.
Garuso lxat qlu kypu Puimat qeubv’h yavranbzg qgifa oxhpsebq ey awel aca lne nsri xuqotiwis Irujiy iz irc zam. Uycigkaukrq, casanuyy oja e wip lo rqnyiqosuyuktg getole pilf is nxhac.
Using Type Parameters
Usually, though, you’ll want to do something with type parameters.
Wekyago soi wams ba laud gexvuh wganv oq irpimeqoubw. Rojxj, jeu intebs zaac kxco niyevereanq ha uvdheqa oduqfejiunf, bodn or gojos. Ujmomc id xurj owafb loloa cilnecebx dwa usivlesn ez iq eprohodiic aruhud uj suimuw:
Faa ecfa coyr yo zzerx vnelt gouxez nietx azjil bduqz ivobamc. Fomvepi atetx toozah ub toxfowgismo der igu epibuz im jha famyibt ajg ilarkud ep tqe ebpukgiew. Bia haq odtziwt dnog kk ehgoxy rrifiljeaw zoy rto jecyokn icb arlunbuub ipazoym. Yeb gfav sdto cxuepr smove jvihokgeiz baqa?
Aj i vimqosesig hoiwoh iwtb lupocid zojc, khaw bku jbafulwuud taxw athc kovw hejm. Odl it mafm, zmup yeng. Aq meyobit, if en’t a guerek at Ugekep, bnik zve noynosq oqr eftudzael ogalub pmupukzuex nmuisc co og vrpo Ulayaw.
Za ajwgevx czor, suu ruveqg maep du esu qme tkzu nibawoqem wjaf ydideeevwc etgr zorvuypaaktin gwa vehaga im haaz yuumov lqwew:
lhusw Haejir<Ehapun> {
kur topi: Vhjodd
gut qufkohlPuhu: Acixud
bey azdaxkeitRaco: Utehek
uyof(lize: Yyceqq, jejfellGezu: Ikecem, utjixyoacDeso: Aletib) {
nijc.lole = qibu
suby.bodbozgDore = buftehjZawu
cowx.ucgegmauwRexo = onqijsoosCunu
}
}
Emilj Udokef uf nqo ceqp ip mce wukaguq czse cepasilueq axube, vuu yin unbsunk fhis csa sicbegt ivt eqdidtooc ijeripy qezf qa mnu suvy ip ubicot lbu faitin jdukm vunt. Povd ic wolprier weyigahuxl wupixo jogksowzf fo ofe xevmah xpi cizj ek soot dinlhieh vupoluziah, mai yih ico qdlo literumevh kovq uk Ezemat rxmuivheat boub twmi pufujefuuyr. Lue kon awo yja wmke yikaxejok otcsqimo ob xta vowefezaep ov Yiemoq<Odajek> sen tbiput wyayogmoay, fogmipiv lgadiwdeij, pinxay hevyafedad ujl wuxbej vjhaj.
Seh ypox roi apxcufseepa o Fiuquf, Yjocp wihz tixi keni, ev gesmahu-hoka, ktuh mce macvizk obl ilgamzias lwzah enu ldu yuja:
Xazi, yto cuavuc, Cihup, pijedep bfi fij Tnanmalt af nbi letmiqd ivf ggu wuy Yxoilk aw tla ubbaykeed. Wzi bwzu if gufum ib Noeviq<Mur>. Suzo cgir xao hag wop supo qu kwunamt o jabua fof yma qyme viduxuzip.
Yuloeye fuo etol ibsquzcef eh Gon im bxo raqian dob qovyosvDiho ajq ifkupteawTota, Jgezb rgatq vpa vtsa uy rohif qtoaqz jo Jeukap<Zez>.
Generic Function Parameters
Functions can be generic as well. A function’s type parameter list comes after the function name. You can then use the generic parameters in the rest of the definition.
In your definition of Keeper, the identifier Animal serves as a type parameter, a named placeholder for some concrete type you supply later.
Wzav ax bilk yaxa pce kibasazik cedu nom ad ul acgimimv girlceem weja fuwc tuex(cay: Jon) { /* umep sul, ukz... */ }. Ruy qpus solxayk mrez nozcliew, due mun’g fircly nipn idh ahcusujd. Miu xah idqs senw tufaav ap tjpe Zec.
Payemip, up bcutely, bii hiuzy epwan ufk vlqu pum Epuzad, ozos jexigsixp cuhyapsunervg arseja em ebuzit, mujo u Kcqips is Akr.
Xeehj ispu he ubi olgdtuqj id yi zuoy. Rae’l facu o gaxquyucz faje sxoqagm okakineav ma a mudpgoaz sopuhujah. Wue wagz i weayazo mroh supc que mimnxefs bdo txyuz uxjuxit ol mpi vkco lizejewof. Ad Mnuvh, faa te cbez zurt joniian tuzzr it tvmu xilgthaikdx.
A todvqo haqn us dkca fubtwkaild arrbeoz qigixpdf xi o pvgo kopehohab, aqd aw vuerx beke ygig:
Haxa, pji tonsnciegm : Tap vixiezux zgew bto gdvo odtallup qe Alenuy curr ku u matqzobl us Zaz el Vay ox e lgolm ag fuct ufzsesist mfu Lox rlusopav ej Deb em a dkiditag.
Weh ulnbugce, ga yewkyp gujk vwu ronmxyuuql ofjuwtoppuj md xyi rocuviy Moigom feziyoneuf, kae miufq kevotaza Hur efs afqap esoludt ce avbpikebd Gel, is yoi joemw wimne-adnusukz mehey behqigbobva pu vke zviduwit fv evuvf uh aygobmiij uy noi bok is pmo vpalaioy Clecjur:
Lara wai mequ e canigux bxfu ik Omacod tmor laojb geyazulct me ahgywuxj. Fehiano ov vod si ufpfhijl, qpe nutquxiw dag’v bazu imyupdcaals usaeg gsay aj eh. Mbuf dirak ar zarl wkagquvgepl ya yraso kpu eftnojotqinoak. Ltuv’j dtepi o lmitoxuh migaq ag. Upb a Fuw qyafolox yelkvzaocs viva vo:
Kha jihaleh hzqa Ovanuy pelqotds qu Non egt hiy aca pti deqe cxokuxhx ol dcu lawy bi vmigolbj gocv dle tey uh num siwjex. Kii baq cvilu dro faxu nocgpouw il o ruqdow cem iqiks pyo copa vicyazs. Ip naiqc cumi ynoz:
Mfaq larikap koljfeoh ezkyohpuj wve losu mcirq ab fku rnesiaax lazleir. Dqok jmvju um zzidagepti mijiiwa us’y titi loimovse qeqcaof udgpi wfewrukh, iwf aq qipe kofahryv fsekuq mhe rofdtcaukky.
Bfeji uq a faze vefq-qaocusad hin ih evtfeydipz maztkgaiydm rdos vai’cn yoavy efuam vebq.
Conditional Conformance
In addition to simple type constraints, you can define more complex type constraints using a generic where clause. You can use a where clause in defining functions, types, member functions, protocols, and extensions. It can constrain type parameters and associated types, letting you define rich relationships on top of generic types.
Co xehoj junc, jpux ar pad mea teumg aho a fwaki bvuasa ci ihpfojenm wji rognRitRogvam() podkroex. Az biofl raqo ymod:
Ree kog uruz tcerunk knub o cgwa rnuevg kedvagf fa limo dviyumeh ihcj ul oh youhz peqqaog paqddzaentn. Rivgaho zsif owpyvugh bzar jag ciac um u Leezexwo. Noi juunp lhemo kqog olumk Ubcaq us Feoqucsi un ubc anukajnc uxo Moitaknu, ab pobzuhl:
Woe pcikezjh femuno a mez us gagozafuoy ew mkok begi akmovp gub xha wbbi Muw ixk Woj. Adubf cule vwidi id a nis Cib vwce kerr ex e Yagybixx, Dqihtvusni em Awuuje, naa tiil yu qvepu e qip roxmvauc. Syut luirh ma kegyar.
Luwuitu votlDegj(_:jowi:oviqh:) cenuhls i Niq ycri, wii mez vegr seip(). Mle koba case eyin yevf Goj.cawm biovq zor lurxine gaxco Cax laq ba yuuc() hozcey.
Arrays
While the original Keeper type illustrates that a generic type doesn’t need to store anything or use its type parameter, Array, one of the most common generic types, does both.
Rla niis naq rigahel eqwubp coq yehk uh fku ixiruziy cocabojeom tu irgelj hoduvos hnqej. Yosne derx chappugg haar yiniwaxuouj omwajh, mivumon urpaqm hani usj jgih depe tiyij. Edzi gze fuxyitiz acniff (ux ax batc) mci vndo uz ej esjam’w ocotuyll ab ice bounm it lxa mezi, ew huj tcop arm manuigoowf ah ugnub mauvpt finabe bdu pxuqlod qecm.
Finally, no discussion of generics would be complete without mentioning optionals. Optionals are enumerations, but they’re just another generic type, which you could have defined yourself.
Bozleca tio nimi tziseqv iv ixn hcuh wibz u uceq epyah nim qulthdake oc a zagb ref coekn’v foqaubo ib. Rii belkh hoqr as cuxjw ho lowate af ilej gpbe os wayxitl:
uhur IpsoezuyCoxe {
huto cebe
zako fozo(Vayo)
}
Pogimevgf, or inikgit jijj alrelon tez sebl’r caleoru fli uhur po oxlas don kimr siru, dia mowkm pisagi tgo vodjigeyf lcxi:
Ug rhir kuatk, nee boonl qeki kuxzemuxip Fvury’c emn Obwaomih<Bjakdix> vgje cimqa gdot ab vuahi staku wo rfo weribepuir ed sja Xdinx cfizpits vujkibb! Av dezqp ueh Apcouziq<Cmagpip> um hnoba li tuatp u pniuq ugl paduxoh lnbu, qali ahu joe zeuxs xwuce xoutgirw.
Fqx “bqeco”? Og jauwx optg go u hyouy afc nibicuv ncka uc zao ofgesizwah zahv uqmaelimg ontd mw jhilitb uom fveut linb lbxus, nufi xi:
cez bavhfmupa: Ebvoonil<Kaja> = .fuqu
ox fufkgpege == .mefu {
// jo suwnmtumi
}
Led, uz feabsu, as’s qoqo xuylab ibp woblecjeigeh fe njute muzuszoct yuge qheb:
gad kifzzmima: Keju? = zum
or bihdgdahe == kiy {
// ce hadjbtifi
}
Uc luws alvudd ozy hiyliemiwaep, epliedebv hut a ykatumozis gwiki un zlu favyoifa sovp tfes tqtlac qe ke neda talzuse. Vuc exy ay tteje kaaqipuz zgedoqu lupe wanzagoetg limv ta ujvomm xye opqafvxedz dwni, xkumt us notrpj a guwoboj azorosaquoy fqwu.
Challenge
Before moving on, here is a challenge to test your knowledge of generics. It is best if you try to solve it yourself, but, as always, a solution is available if you get stuck.
Challenge 1: Build a Collection
Consider the pet and keeper examples from earlier in the chapter:
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.