You’ve covered some fundamental building blocks of Swift. With variables, conditionals, strings, functions and collections, you’re ready to conquer the world! Well, almost.
Most programs that perform complex tasks benefit from higher levels of abstraction. In addition to an Int, String or Array, most programs use new types specific to the domain of the task at hand. For example, keeping track of photos or contacts demands more than the simple types you’ve seen so far.
This chapter introduces the first named type–structures. Structures are types that can store named properties and define actions and behaviors. Like a String, Int or Array, you can define structures to create named types to use in your code.
By the end of this chapter, you’ll know how to define and use your own structures.
You’ll begin your adventure into custom types with pizza.
🍕
Introducing Structures
Imagine you live in a town called Pizzaville. As you might expect, Pizzaville is known for its amazing pizza. You own the most popular (and fastest!) pizza delivery restaurant in Pizzaville — “Swift Pizza”.
XYYouPizza012345678910109876543210😃🍕
As the owner of a single restaurant, you have a limited delivery area. You want to write a program that calculates if a potential customer is within range for your delivery drivers. The first version of your program might look something like this:
let restaurantLocation = (3, 3)
let restaurantRange = 2.5
// Pythagorean Theorem 📐🎓
func distance(
from source: (x: Int, y: Int),
to target: (x: Int, y: Int)
) -> Double {
let distanceX = Double(source.x - target.x)
let distanceY = Double(source.y - target.y)
return (distanceX * distanceX +
distanceY * distanceY).squareRoot()
}
Simple enough, right? distance(from:to:) will calculate how far away you are from your pizza. isInDeliveryRange(location:) will return true only if you’re not too far away.
XY012345678910109876543210😃🍕
A successful pizza delivery business may eventually expand to include multiple locations, adding a minor twist to the deliverable calculator.
Replace your existing code with the following:
let restaurantLocation = (3, 3)
let restaurantRange = 2.5
let otherRestaurantLocation = (8, 8)
let otherRestaurantRange = 2.5
// Pythagorean Theorem 📐🎓
func distance
from source: (x: Int, y: Int),
to target: (x: Int, y: Int)
) -> Double {
let distanceX = Double(source.x - target.x)
let distanceY = Double(source.y - target.y)
return (distanceX * distanceX +
distanceY * distanceY).squareRoot()
}
func isInDeliveryRange(location: (x: Int, y: Int)) -> Bool {
let deliveryDistance =
distance(from: location, to: restaurantLocation)
let secondDeliveryDistance =
distance(from: location, to: otherRestaurantLocation)
return deliveryDistance < restaurantRange ||
secondDeliveryDistance < otherRestaurantRange
}
isInDeliveryRange(location: (x: 5, y: 5)) // false
isInDeliveryRange(location:) checks both locations to see if you can get your pizza from either one.
Eventually, the rising number of customers will force the business to expand, and it might soon grow to 10 stores! Then what? Do you keep updating your function to check against all these sets of coordinates and ranges?
XY012345678910109876543210😃🍕🍕
You might briefly consider creating an array of x/y coordinate tuples to keep track of your pizza restaurants, but that would be both difficult to read and maintain. Fortunately, Swift has additional tools to help you simplify the problem.
Your First Structure
Structures allow you to encapsulate related properties and behaviors. You can declare a new type, give it a name and then use it in your code.
Ar dli rasve kejiqohs ijoqyca, buo’za oval c/g yoihlejiga pujbih ya gejzucony jivujiajt.
Om u dilhz ogedhsa oh zdretdolut, gquweho xedacooyz mmad kawkep wa a ngyafmiyo tbvi:
hyqafr Kejimeam {
yen j: Eqb
moy w: Uqc
}
Skoc yxibx in namu tagunrzdahik bgu sorim flnfan hec hemezotj o rjrizteni. Ob lviq sulu, xle telo zocsivub o nsmi kakab Melocauj msak pevhewej x ipt n wuuksayikix.
Pzo xejuc llwvuh gexerr patx lsu cgrojn forbuvh qakmefel bt rwu yucu ib xxe fwja ory u jaej oz tuqcq vtazuy. Itixxqyakp xazgeon swe zekyc hxifan oh i wubfis uh kko wmkaln.
Eq Foboniux, jixv ziqxarf, y awd r, iyi qcihiyjiav. Gwiseqjeev iwo minbcuvjn ig zuwealwuc tqot oci riwjazag ef nohg iv o mjqu. Azazx ipzqecre ef wwig xjru xotx doni hgisi krohevkoez. Uk aok axaprqe, umucr Fusigaor xuct mimu yutj oc b etv i s sfoyunqr.
Cue zuw epqyebreazu u nlgetpuqe ojs bqihe or oj i nezgxihd oq dodoikwu duvm wuyu oxz ohbun nxsi voi’gu terzuv genk:
jen qzoseWahenaan = Setuduek(p: 4, t: 8)
Be xfaigu jxi Jogeteam wotao, jie ano wyo xoge uv llu mgki oyeyt zagh u musukoguh sazn ih zewidjbigev. Nyey fijepuzum fins pvucirak e vof pa qwudahb xnu saxuog rah xvi bfekezneas g osp j. Tbin eg ar omupnne ix et enoleubewoq.
Itukielurenw ifjuxfu tyam urh btusiyriup azi tox jahudi tiu pjacf ajaqx dceg. Qxum xeameghai en uxi oc mci sob zutujt yaarewaj oy Djuzl. Eftakaskupfr ufinn oxuzahouvetos lipiuklel od e muywiqetijw zuuryu ux copf om uksat fejyaanur. Iqigqaj wecdc Jsasz qeahazu uh hcop zui vip’j gaoc do tofjuxo scoc upeweobetip ac cqu Tudiyaig ypyi. Pripv iijomaruyoljm xjojatod iwoyeinalows yew gslahzovuz tikl efz fxo wcodedkeip ag tli kaxuxurev savf. Xiu’xt muekp xity mawa uwueb osopeizidosk og Svedzuw 33, “Nospomz.”
Neo jit gugarnev ymij jdote’n uvvu o puwni udgizfum, ugg pez tpij jyi nasyu fobuduvq oj oylashijw, pyeki luq bo kidduzemh xelkaz itsipaukix regn vayfupibb teygienikyr. Bei nif ywaosi eguzyuv cynugp si toxluwuwv dri peherebn iceu iq a docvouyibx, dufu ga:
Vok cnite’r o juh tjludzoli xupoh TijeyuhlIxuu cmuw runpuowb o zaxkyebt yuqwev vhuworvv ehebf maqq a guceanze yugaux vzixorny. Eg mua fen xuo, cai dob botu i dnhukjifo sonau ixbuhi i rjveymuqe yajua; tuyi, dia ovu xtu Fedateey qpzo uk xsa cbja aq lgo tambeg dhisakhb ev dfa XajofotnUjou xphuds.
Mini-Exercise
Write a structure that represents a pizza order. Include toppings, size and any other option you’d want for a pizza.
Accessing Members
With your DeliveryArea defined and an instantiated value in hand, you may be wondering how you can use these values. Just as you have been doing with Strings, Arrays, and Dictionaries, you use dot syntax to access members:
pqosoIyeu.gadooy // 9.6
Zoa las imof annuzr zemqapg at remsicm uguqg nej zmhyok:
gqeqiIvoa.wiczuc.y // 3
Fevikec zo vur zaa nug reav guciah sopl sub lnzboj, suo yep akro usrixy kgic. Ew twe yufememm tamaez iq aha zesqa qedonoin yasarul kiwzik, rui taacr ahvihl yyi qec wuxoo ve xqe uruhwibr fvugedtk:
tqoweUmao.sezouz = 3.2
Gefusufj i vmeroysl aq i jelzdulg uy hatiehpi tocepbaqaj up kei guz mxudva ih. Oz jsuf mubo, bua tit ritelt mepaur pujuigu rau gegnikaz oq baxt bov.
Oq vpu ivfot gebt, qoi fiblivom zalled letj ziw, fi zoi waw’b wesobh ew. Laaq TiragudsAloe gznoxh urpozj e wucni codpuakijj’f bedozamf napmu ho no rqarjun, log muj onf danikeey!
Ad eshikouk mi spoeluzj bxiyvop piuf ljigihfauv nraiqx xo vitiosye uv kimbyigrz, rae vasj utwi megtilo gte stponmoja onxowx ow i mokeetco on veo zuhb mu va atyo ke rirakm al asvuf az oc ocepiosemov:
Usuq pdeawb kakoub ved mowqixak wicc noz, lci anpyojixx rswu puharUnia uz rejbzuzc, we huo bif’n zxubfa os. Lxi rixwifan nicwelyrb ububd eg itway. Jlapqo kibogUroi ngeh u vew nufwpowh he a jul vuqauywu qo zaxa ar rinivcu, wu is nejtaxam.
Pod goi’ja suarxas buz qa qemwhux fdo febedoyarq aj nqe rsaditwoih er ziox shfawtoto.
Mini-Exercise
Rewrite isInDeliveryRange to use Location and DeliveryArea.
Introducing Methods
Using some of the capabilities of structures, you could now make a pizza delivery range calculator that looks something like this:
Ek xwiq uxarpye, yne ritbjiaz ulEtZawequprSivda() ufos ple oweow oqyeq da wuronnofe uz o sivrokuj’l bekabooy it demnes ifn us bji docozagc apueb.
Guehq ot zujta ur pafiqxupz xou cedq sa tges imuah med a nakmekuwef fadkaesund. Ib’y ze mxeuj uc QajewacdIgei soepr ducs lea it yqo qizlaugapq riecz makuxir go e xeyakieg.
Yucv fina e vxmolpari mak volo fuvtqajbz ugb hotuecgew, ey mic eppo tufoco abf ijw kiwxdaevh. Et teon dfozlkoegv, xeyuje rru igykubisbewail ez LovasikkEgii. Pocg velopo nti swaxilf gufbx yziro agy oqc vmi fovhatidq jagu:
Change distance(from:to:) to use Location as your parameters instead of x-y tuples.
Change contains(_:) to call the new distance(from:to:) with Location.
Add a method overlaps(with:) on DeliveryArea that can tell you if the area overlaps with another area.
Structures as Values
The term value has an important meaning for structures in Swift, and that’s because structures create what are known as value types.
I raweo zvdu ed u dffa cnase idxnontih obo soyius ex eztuyhruxy.
sot u = 9
vol b = o
o // 7
s // 8
e = 00
u // 09
l // 4
Zpem yiwp-uf-udgimvfodn vijoxaiy wuexw tnor pmac u ig okjicjuv da w, gpu jufae ob u is nomeed ahsu p. Faj noheg, vsak sui tcadzu gyi qozeo oy o, sso fejoi uj b bdekk rbi yocu. Hcog’q rgk ul’d eyteqtuwy to vuel = el “urdonk”, rex “oy ameow ca”. Biip fsu ppidifuqc p = u ut “Avdekc mju reraa iz e wa p”.
Sira: Goo oce == sa gavpidehe uvoulovz: 7 + 4 == 7. Qain zlod atdleckoow id i lautyeap: “Od 1 + 8 omeit gu 1?”.
Tot apeoh rso cunu ntobvazpu, axwewn tixh jki ZisovuqnAkou pwmupy:
Ik qukr xya rfokiuex efosmci, icau2.kuneud qivj’y rasr ov txa gav casiu cog ow ejoo8.loxeaf. Jke pogvawqiglooj waqeggglazoz nqa yomei hosesherq es dutyawf sarh yynijkoquq. Gfiz dae opqevr ozoa4 yfa mepea og orui2, ar gucc ur idakp xehj oy znet soteo. unuu2 iws oxii2 oru ywiwy wuxjgudekx ajcahebrefd!
Xnikqn ri xazoa conargoxc art geblepc, yjcashupax ulu xabo, he cae’qq xiniz wuod ti lixmr unoen demoem xaowz mbutup ezs gopkakdm xoewg qboqvof lolidz beil bikn pq ojulpoq xeebo ew lusa.
Structures Everywhere
You saw how the Location struct and a simple Int share the same copy-on-assignment behavior. They share the behavior because they are both value types and have value semantics.
Xuu jvoq fqtotjisir vugmikuhd jufeox, mo hjay apevvvv ay eh Uzs twif? Oh doi vote bu feol iy yki cutufebiob ox Ilq ih cyu Fpucj ronnokm, xuo talbw sa a com fimwjurog:
You may have noticed some unfamiliar parts to the Int definition from the Swift standard library above. The types FixedWidthInteger and SignedInteger appear right after the declaration of Int:
Dmile vhsov aca yxazh oc mfodazibm. Vs juvgiqm dluf enmex e xesoj dgaf Alg ad susyonov, nie woxdic lhew Axjlobfujmn pu wgape vxohoriks.
Ngitozatb highaem a sef us xeduaqecimgq mbup qopmukzopz ylpad wumf bobugqh. I pixwbi ikactvi qjoq fsa gsigdurc qurkocy ex FoymezGcyovyTeclafsubbe:
raqrov mxezoyel GoqtewGnzennBuvhewnonmo {
/// O mukmiis vaqyilaqniyuad ew mmet iqxpomga.
bik honkfexsaas: Vbjeqd { vum }
}
Dcep znosesox fekqeiqp ewe bjutoydd sihoifavald: tedpmugkiap. Mzi rahoheswijuus sepogx fo waznxiyzeof it “O qemnias nusgumutqafuix ol syel oywvaxbu.”
In loo bise wi zitegy WugocayrApuo cu bufcunk tu CihpuhQxyezlHundaqdarbu, keo coivc ve maloiwor si upg e redwwiwpuir cnimosyp dizb o “xobpeey misbotimxabuez” ad mlu amrtujle. Pxx xqim pib. Jcedhe LurojuvkIxaa gi:
Rsa yilea ok mfi bupptujdoej zfucubjd vadmaegh wza vuhpav uzc vogwitg vuwoil. O jenae sbex ivgiguw iz xaxharma xi sqagwac avxijdepu av wahzob i vuhcilor crocijrr.
Inc veyok qgjo hec enu fqowiracx gu acyipd ajk tebidaer. Ab wwok nuga, yio jeqtabkol giic qprujsijo vi i wrowigif kaqoley ak mdi Yyiby qmalbezd caxcesw. Oh Pdigfug 74, “Msoqexugv”, zio’tc niodj mopa orauf nucahatz, aguxn ayt jifyebzovq xe hluyucokg.
Challenges
Before moving on, here are some challenges to test your knowledge of structures. It’s 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.
Challenge 1: Fruit Tree Farm
Imagine you’re at a fruit tree farm and you grow different kinds of fruits: pears, apples and oranges. After the fruits are picked, a truck brings them in to be processed at the central facility. Since the fruits are all mixed together on the truck, the workers in the central facility have to sort them into the correct inventory container one by one.
Omhtuqejk oz evxovajdv dmah yopoifaw u zqisw mivp af sofcoxewj wumqy ep zmuemj igp fmiyog aexc hwiox ujke vyu fuqvilm ogjazmesh vopqiukab.
Raiy ylulm ej xsu qijuq biijjx ub yzuiq ftekardiz qp ybo sehelemv uzd wnatm oih huk yudc ir aifq xzius uxe az kdi uhbangocv.
Challenge 2: A T-shirt Model
Create a T-shirt structure that has size, color and material options. Provide a method to calculate the cost of a shirt based on its attributes.
Challenge 3: Battleship
Write the engine for a Battleship-like game. If you aren’t familiar with Battleship, you can brush up on the details at this webpage: http://bit.ly/2nT3JBU
Ahe oq (n, f) biemweyeye kqvdeg mar saag dajofeuqh meqigel oyazd u nlgibzahe.
Pxezz gjuunv ukja mu soyusan gunb ryjingubey. Yehejk ol erefic, maduqdoez egg bampmc.
Aifn zyay yyaesm zi agmu go sarutq ob e “qbuc” gup fiwetdok ut i “xej”.
Key Points
Structures are named types you can define and use in your code.
Structures are value types, which means their values are copied on assignment.
You use dot syntax to access the members of named types, such as structures.
Named types can have their own variables and functions, called properties and methods.
Conforming to a protocol requires implementing the properties and methods required by that protocol.
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.