Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... ·...

764

Transcript of Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... ·...

Page 1: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language
MP
Linia
Page 2: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

WelcometoSwift

Page 3: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AboutSwift

Swiftisafantasticwaytowritesoftware,whetherit’sforphones,desktops,servers,oranythingelsethatrunscode.It’sasafe,fast,andinteractiveprogramminglanguagethatcombinesthebestinmodernlanguagethinkingwithwisdomfromthewiderAppleengineeringcultureandthediversecontributionsfromitsopen-sourcecommunity.Thecompilerisoptimizedforperformanceandthelanguageisoptimizedfordevelopment,withoutcompromisingoneither.

Swiftisfriendlytonewprogrammers.It’sanindustrial-qualityprogramminglanguagethat’sasexpressiveandenjoyableasascriptinglanguage.WritingSwiftcodeinaplaygroundletsyouexperimentwithcodeandseetheresultsimmediately,withouttheoverheadofbuildingandrunninganapp.

Swiftdefinesawaylargeclassesofcommonprogrammingerrorsbyadoptingmodernprogrammingpatterns:

Variablesarealwaysinitializedbeforeuse.

Arrayindicesarecheckedforout-of-boundserrors.

Integersarecheckedforoverflow.

Optionalsensurethatnilvaluesarehandledexplicitly.

Memoryismanagedautomatically.

Errorhandlingallowscontrolledrecoveryfromunexpectedfailures.

Swiftcodeiscompiledandoptimizedtogetthemostoutofmodernhardware.Thesyntaxandstandardlibraryhavebeendesignedbasedontheguidingprinciplethattheobviouswaytowriteyourcodeshouldalsoperformthebest.ItscombinationofsafetyandspeedmakeSwiftanexcellentchoiceforeverythingfrom“Hello,world!”toanentireoperatingsystem.

Swiftcombinespowerfultypeinferenceandpatternmatchingwithamodern,lightweightsyntax,allowingcomplexideastobeexpressedinaclearand

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 4: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

concisemanner.Asaresult,codeisnotjusteasiertowrite,buteasiertoreadandmaintainaswell.

Swifthasbeenyearsinthemaking,anditcontinuestoevolvewithnewfeaturesandcapabilities.OurgoalsforSwiftareambitious.Wecan’twaittoseewhatyoucreatewithit.

Page 5: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

VersionCompatibility

ThisbookdescribesSwift5.1,thedefaultversionofSwiftthat’sincludedinXcode11.YoucanuseXcode11tobuildtargetsthatarewrittenineitherSwift5.1,Swift4.2,orSwift4.

WhenyouuseXcode11tobuildSwift4andSwift4.2code,mostSwift5.1functionalityisavailable.Thatsaid,thefollowingchangesareavailableonlytocodethatusesSwift5.1orlater:

FunctionsthatreturnanopaquetyperequiretheSwift5.1runtime.

Thetry?expressiondoesn’tintroduceanextralevelofoptionalitytoexpressionsthatalreadyreturnoptionals.

Largeintegerliteralinitializationexpressionsareinferredtobeofthecorrectintegertype.Forexample,UInt64(0xffff_ffff_ffff_ffff)evaluatestothecorrectvalueratherthanoverflowing.

AtargetwritteninSwift5.1candependonatargetthat’swritteninSwift4.2orSwift4,andviceversa.Thismeans,ifyouhavealargeprojectthat’sdividedintomultipleframeworks,youcanmigrateyourcodefromSwift4toSwift5.1oneframeworkatatime.

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 6: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ASwiftTour

Traditionsuggeststhatthefirstprograminanewlanguageshouldprintthewords“Hello,world!”onthescreen.InSwift,thiscanbedoneinasingleline:

1 print("Hello,world!")

2 //Prints"Hello,world!"

IfyouhavewrittencodeinCorObjective-C,thissyntaxlooksfamiliartoyou—inSwift,thislineofcodeisacompleteprogram.Youdon’tneedtoimportaseparatelibraryforfunctionalitylikeinput/outputorstringhandling.Codewrittenatglobalscopeisusedastheentrypointfortheprogram,soyoudon’tneedamain()function.Youalsodon’tneedtowritesemicolonsattheendofeverystatement.

ThistourgivesyouenoughinformationtostartwritingcodeinSwiftbyshowingyouhowtoaccomplishavarietyofprogrammingtasks.Don’tworryifyoudon’tunderstandsomething—everythingintroducedinthistourisexplainedindetailintherestofthisbook.

NOTE

OnaMacwithXcodeinstalled,oronaniPadwithSwiftPlaygrounds,youcanopenthischapterasaplayground.Playgroundsallowyoutoeditthecodelistingsandseetheresultimmediately.

DownloadPlayground

SimpleValues

Uselettomakeaconstantandvartomakeavariable.Thevalueofaconstantdoesn’tneedtobeknownatcompiletime,butyoumustassignitavalueexactlyonce.Thismeansyoucanuseconstantstonameavaluethatyoudetermineoncebutuseinmanyplaces.

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
Page 7: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 varmyVariable=42

2 myVariable=50

3 letmyConstant=42

Aconstantorvariablemusthavethesametypeasthevalueyouwanttoassigntoit.However,youdon’talwayshavetowritethetypeexplicitly.Providingavaluewhenyoucreateaconstantorvariableletsthecompilerinferitstype.Intheexampleabove,thecompilerinfersthatmyVariableisanintegerbecauseitsinitialvalueisaninteger.

Iftheinitialvaluedoesn’tprovideenoughinformation(orifthereisnoinitialvalue),specifythetypebywritingitafterthevariable,separatedbyacolon.

1 letimplicitInteger=70

2 letimplicitDouble=70.0

3 letexplicitDouble:Double=70

EXPER IMENT

CreateaconstantwithanexplicittypeofFloatandavalueof4.

Valuesareneverimplicitlyconvertedtoanothertype.Ifyouneedtoconvertavaluetoadifferenttype,explicitlymakeaninstanceofthedesiredtype.

1 letlabel="Thewidthis"

2 letwidth=94

3 letwidthLabel=label+String(width)

EXPER IMENT

TryremovingtheconversiontoStringfromthelastline.Whaterrordoyouget?

There’sanevensimplerwaytoincludevaluesinstrings:Writethevalueinparentheses,andwriteabackslash(\)beforetheparentheses.Forexample:

MP
Prostokąt
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 8: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letapples=3

2 letoranges=5

3 letappleSummary="Ihave\(apples)apples."

4 letfruitSummary="Ihave\(apples+oranges)piecesof

fruit."

EXPER IMENT

Use\()toincludeafloating-pointcalculationinastringandtoincludesomeone’snameinagreeting.

Usethreedoublequotationmarks(""")forstringsthattakeupmultiplelines.Indentationatthestartofeachquotedlineisremoved,aslongasitmatchestheindentationoftheclosingquotationmarks.Forexample:

1 letquotation="""

2 Isaid"Ihave\(apples)apples."

3 AndthenIsaid"Ihave\(apples+oranges)piecesoffruit."

4 """

Createarraysanddictionariesusingbrackets([]),andaccesstheirelementsbywritingtheindexorkeyinbrackets.Acommaisallowedafterthelastelement.

1 varshoppingList=["catfish","water","tulips"]

2 shoppingList[1]="bottleofwater"

3

4 varoccupations=[

5 "Malcolm":"Captain",

6 "Kaylee":"Mechanic",

7 ]

8 occupations["Jayne"]="PublicRelations"

Arraysautomaticallygrowasyouaddelements.

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 9: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 shoppingList.append("bluepaint")

2 print(shoppingList)

Tocreateanemptyarrayordictionary,usetheinitializersyntax.

1 letemptyArray=[String]()

2 letemptyDictionary=[String:Float]()

Iftypeinformationcanbeinferred,youcanwriteanemptyarrayas[]andanemptydictionaryas[:]—forexample,whenyousetanewvalueforavariableorpassanargumenttoafunction.

1 shoppingList=[]

2 occupations=[:]

ControlFlow

Useifandswitchtomakeconditionals,andusefor-in,while,andrepeat-whiletomakeloops.Parenthesesaroundtheconditionorloopvariableareoptional.Bracesaroundthebodyarerequired.

1 letindividualScores=[75,43,103,87,12]

2 varteamScore=0

3 forscoreinindividualScores{

4 ifscore>50{

5 teamScore+=3

6 }else{

7 teamScore+=1

8 }

9 }

10 print(teamScore)

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Linia
Page 10: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

11 //Prints"11"

Inanifstatement,theconditionalmustbeaBooleanexpression—thismeansthatcodesuchasifscore{...}isanerror,notanimplicitcomparisontozero.

Youcanuseifandlettogethertoworkwithvaluesthatmightbemissing.Thesevaluesarerepresentedasoptionals.Anoptionalvalueeithercontainsavalueorcontainsniltoindicatethatavalueismissing.Writeaquestionmark(?)afterthetypeofavaluetomarkthevalueasoptional.

1 varoptionalString:String?="Hello"

2 print(optionalString==nil)

3 //Prints"false"

4

5 varoptionalName:String?="JohnAppleseed"

6 vargreeting="Hello!"

7 ifletname=optionalName{

8 greeting="Hello,\(name)"

9 }

EXPER IMENT

ChangeoptionalNametonil.Whatgreetingdoyouget?AddanelseclausethatsetsadifferentgreetingifoptionalNameisnil.

Iftheoptionalvalueisnil,theconditionalisfalseandthecodeinbracesisskipped.Otherwise,theoptionalvalueisunwrappedandassignedtotheconstantafterlet,whichmakestheunwrappedvalueavailableinsidetheblockofcode.

Anotherwaytohandleoptionalvaluesistoprovideadefaultvalueusingthe??operator.Iftheoptionalvalueismissing,thedefaultvalueisusedinstead.

1 letnickName:String?=nil

2 letfullName:String="JohnAppleseed"

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 11: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 letinformalGreeting="Hi\(nickName??fullName)"

Switchessupportanykindofdataandawidevarietyofcomparisonoperations—theyaren’tlimitedtointegersandtestsforequality.

1 letvegetable="redpepper"

2 switchvegetable{

3 case"celery":

4 print("Addsomeraisinsandmakeantsonalog.")

5 case"cucumber","watercress":

6 print("Thatwouldmakeagoodteasandwich.")

7 caseletxwherex.hasSuffix("pepper"):

8 print("Isitaspicy\(x)?")

9 default:

10 print("Everythingtastesgoodinsoup.")

11 }

12 //Prints"Isitaspicyredpepper?"

EXPER IMENT

Tryremovingthedefaultcase.Whaterrordoyouget?

Noticehowletcanbeusedinapatterntoassignthevaluethatmatchedthepatterntoaconstant.

Afterexecutingthecodeinsidetheswitchcasethatmatched,theprogramexitsfromtheswitchstatement.Executiondoesn’tcontinuetothenextcase,sothereisnoneedtoexplicitlybreakoutoftheswitchattheendofeachcase’scode.

Youusefor-intoiterateoveritemsinadictionarybyprovidingapairofnamestouseforeachkey-valuepair.Dictionariesareanunorderedcollection,sotheirkeysandvaluesareiteratedoverinanarbitraryorder.

1 letinterestingNumbers=[

MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 12: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 "Prime":[2,3,5,7,11,13],

3 "Fibonacci":[1,1,2,3,5,8],

4 "Square":[1,4,9,16,25],

5 ]

6 varlargest=0

7 for(kind,numbers)ininterestingNumbers{

8 fornumberinnumbers{

9 ifnumber>largest{

10 largest=number

11 }

12 }

13 }

14 print(largest)

15 //Prints"25"

EXPER IMENT

Addanothervariabletokeeptrackofwhichkindofnumberwasthelargest,aswellaswhatthatlargestnumberwas.

Usewhiletorepeatablockofcodeuntilaconditionchanges.Theconditionofaloopcanbeattheendinstead,ensuringthattheloopisrunatleastonce.

1 varn=2

2 whilen<100{

3 n*=2

4 }

5 print(n)

6 //Prints"128"

7

8 varm=2

9 repeat{

MP
Linia
MP
Linia
MP
Linia
MP
Linia
Page 13: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

10 m*=2

11 }whilem<100

12 print(m)

13 //Prints"128"

Youcankeepanindexinaloopbyusing..<tomakearangeofindexes.

1 vartotal=0

2 foriin0..<4{

3 total+=i

4 }

5 print(total)

6 //Prints"6"

Use..<tomakearangethatomitsitsuppervalue,anduse...tomakearangethatincludesbothvalues.

FunctionsandClosures

Usefunctodeclareafunction.Callafunctionbyfollowingitsnamewithalistofargumentsinparentheses.Use->toseparatetheparameternamesandtypesfromthefunction’sreturntype.

1 funcgreet(person:String,day:String)->String{

2 return"Hello\(person),todayis\(day)."

3 }

4 greet(person:"Bob",day:"Tuesday")

EXPER IMENT

Removethedayparameter.Addaparametertoincludetoday’slunchspecialinthegreeting.

MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Linia
MP
Linia
Page 14: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Bydefault,functionsusetheirparameternamesaslabelsfortheirarguments.Writeacustomargumentlabelbeforetheparametername,orwrite_tousenoargumentlabel.

1 funcgreet(_person:String,onday:String)->String{

2 return"Hello\(person),todayis\(day)."

3 }

4 greet("John",on:"Wednesday")

Useatupletomakeacompoundvalue—forexample,toreturnmultiplevaluesfromafunction.Theelementsofatuplecanbereferredtoeitherbynameorbynumber.

1 funccalculateStatistics(scores:[Int])->(min:Int,max:Int,

sum:Int){

2 varmin=scores[0]

3 varmax=scores[0]

4 varsum=0

5

6 forscoreinscores{

7 ifscore>max{

8 max=score

9 }elseifscore<min{

10 min=score

11 }

12 sum+=score

13 }

14

15 return(min,max,sum)

16 }

17 letstatistics=calculateStatistics(scores:[5,3,100,3,

MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Linia
MP
Linia
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
Page 15: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9])

18 print(statistics.sum)

19 //Prints"120"

20 print(statistics.2)

21 //Prints"120"

Functionscanbenested.Nestedfunctionshaveaccesstovariablesthatweredeclaredintheouterfunction.Youcanusenestedfunctionstoorganizethecodeinafunctionthatislongorcomplex.

1 funcreturnFifteen()->Int{

2 vary=10

3 funcadd(){

4 y+=5

5 }

6 add()

7 returny

8 }

9 returnFifteen()

Functionsareafirst-classtype.Thismeansthatafunctioncanreturnanotherfunctionasitsvalue.

1 funcmakeIncrementer()->((Int)->Int){

2 funcaddOne(number:Int)->Int{

3 return1+number

4 }

5 returnaddOne

6 }

7 varincrement=makeIncrementer()

8 increment(7)

MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
MP
Prostokąt
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
Page 16: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Afunctioncantakeanotherfunctionasoneofitsarguments.

1 funchasAnyMatches(list:[Int],condition:(Int)->Bool)->

Bool{

2 foriteminlist{

3 ifcondition(item){

4 returntrue

5 }

6 }

7 returnfalse

8 }

9 funclessThanTen(number:Int)->Bool{

10 returnnumber<10

11 }

12 varnumbers=[20,19,7,12]

13 hasAnyMatches(list:numbers,condition:lessThanTen)

Functionsareactuallyaspecialcaseofclosures:blocksofcodethatcanbecalledlater.Thecodeinaclosurehasaccesstothingslikevariablesandfunctionsthatwereavailableinthescopewheretheclosurewascreated,eveniftheclosureisinadifferentscopewhenitisexecuted—yousawanexampleofthisalreadywithnestedfunctions.Youcanwriteaclosurewithoutanamebysurroundingcodewithbraces({}).Useintoseparatetheargumentsandreturntypefromthebody.

1 numbers.map({(number:Int)->Intin

2 letresult=3*number

3 returnresult

4 })

EXPER IMENT

Rewritetheclosuretoreturnzeroforalloddnumbers.

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Prostokąt
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
MP
Linia
Page 17: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youhaveseveraloptionsforwritingclosuresmoreconcisely.Whenaclosure’stypeisalreadyknown,suchasthecallbackforadelegate,youcanomitthetypeofitsparameters,itsreturntype,orboth.Singlestatementclosuresimplicitlyreturnthevalueoftheironlystatement.

1 letmappedNumbers=numbers.map({numberin3*number})

2 print(mappedNumbers)

3 //Prints"[60,57,21,36]"

Youcanrefertoparametersbynumberinsteadofbyname—thisapproachisespeciallyusefulinveryshortclosures.Aclosurepassedasthelastargumenttoafunctioncanappearimmediatelyaftertheparentheses.Whenaclosureistheonlyargumenttoafunction,youcanomittheparenthesesentirely.

1 letsortedNumbers=numbers.sorted{$0>$1}

2 print(sortedNumbers)

3 //Prints"[20,19,12,7]"

ObjectsandClasses

Useclassfollowedbytheclass’snametocreateaclass.Apropertydeclarationinaclassiswrittenthesamewayasaconstantorvariabledeclaration,exceptthatitisinthecontextofaclass.Likewise,methodandfunctiondeclarationsarewrittenthesameway.

1 classShape{

2 varnumberOfSides=0

3 funcsimpleDescription()->String{

4 return"Ashapewith\(numberOfSides)sides."

5 }

6 }

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 18: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

EXPER IMENT

Addaconstantpropertywithlet,andaddanothermethodthattakesanargument.

Createaninstanceofaclassbyputtingparenthesesaftertheclassname.Usedotsyntaxtoaccessthepropertiesandmethodsoftheinstance.

1 varshape=Shape()

2 shape.numberOfSides=7

3 varshapeDescription=shape.simpleDescription()

ThisversionoftheShapeclassismissingsomethingimportant:aninitializertosetuptheclasswhenaninstanceiscreated.Useinittocreateone.

1 classNamedShape{

2 varnumberOfSides:Int=0

3 varname:String

4

5 init(name:String){

6 self.name=name

7 }

8

9 funcsimpleDescription()->String{

10 return"Ashapewith\(numberOfSides)sides."

11 }

12 }

Noticehowselfisusedtodistinguishthenamepropertyfromthenameargumenttotheinitializer.Theargumentstotheinitializerarepassedlikeafunctioncallwhenyoucreateaninstanceoftheclass.Everypropertyneedsavalueassigned—eitherinitsdeclaration(aswithnumberOfSides)orintheinitializer(aswithname).

Usedeinittocreateadeinitializerifyouneedtoperformsomecleanupbefore

MP
Wyróżnianie
MP
Wyróżnianie
MP
Linia
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
MP
Prostokąt
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 19: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

theobjectisdeallocated.

Subclassesincludetheirsuperclassnameaftertheirclassname,separatedbyacolon.Thereisnorequirementforclassestosubclassanystandardrootclass,soyoucanincludeoromitasuperclassasneeded.

Methodsonasubclassthatoverridethesuperclass’simplementationaremarkedwithoverride—overridingamethodbyaccident,withoutoverride,isdetectedbythecompilerasanerror.Thecompileralsodetectsmethodswithoverridethatdon’tactuallyoverrideanymethodinthesuperclass.

1 classSquare:NamedShape{

2 varsideLength:Double

3

4 init(sideLength:Double,name:String){

5 self.sideLength=sideLength

6 super.init(name:name)

7 numberOfSides=4

8 }

9

10 funcarea()->Double{

11 returnsideLength*sideLength

12 }

13

14 overridefuncsimpleDescription()->String{

15 return"Asquarewithsidesoflength\(sideLength)."

16 }

17 }

18 lettest=Square(sideLength:5.2,name:"mytestsquare")

19 test.area()

20 test.simpleDescription()

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
MP
Linia
MP
Wyróżnianie
Page 20: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

EXPER IMENT

MakeanothersubclassofNamedShapecalledCirclethattakesaradiusandanameasargumentstoitsinitializer.Implementanarea()andasimpleDescription()methodontheCircleclass.

Inadditiontosimplepropertiesthatarestored,propertiescanhaveagetterandasetter.

1 classEquilateralTriangle:NamedShape{

2 varsideLength:Double=0.0

3

4 init(sideLength:Double,name:String){

5 self.sideLength=sideLength

6 super.init(name:name)

7 numberOfSides=3

8 }

9

10 varperimeter:Double{

11 get{

12 return3.0*sideLength

13 }

14 set{

15 sideLength=newValue/3.0

16 }

17 }

18

19 overridefuncsimpleDescription()->String{

20 return"Anequilateraltrianglewithsidesoflength\

(sideLength)."

21 }

22 }

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Prostokąt
MP
Wyróżnianie
Page 21: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

23 vartriangle=EquilateralTriangle(sideLength:3.1,name:"a

triangle")

24 print(triangle.perimeter)

25 //Prints"9.3"

26 triangle.perimeter=9.9

27 print(triangle.sideLength)

28 //Prints"3.3000000000000003"

Inthesetterforperimeter,thenewvaluehastheimplicitnamenewValue.Youcanprovideanexplicitnameinparenthesesafterset.

NoticethattheinitializerfortheEquilateralTriangleclasshasthreedifferentsteps:

1. Settingthevalueofpropertiesthatthesubclassdeclares.

2. Callingthesuperclass’sinitializer.

3. Changingthevalueofpropertiesdefinedbythesuperclass.Anyadditionalsetupworkthatusesmethods,getters,orsetterscanalsobedoneatthispoint.

Ifyoudon’tneedtocomputethepropertybutstillneedtoprovidecodethatisrunbeforeandaftersettinganewvalue,usewillSetanddidSet.Thecodeyouprovideisrunanytimethevaluechangesoutsideofaninitializer.Forexample,theclassbelowensuresthatthesidelengthofitstriangleisalwaysthesameasthesidelengthofitssquare.

1 classTriangleAndSquare{

2 vartriangle:EquilateralTriangle{

3 willSet{

4 square.sideLength=newValue.sideLength

5 }

6 }

MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
MP
Wyróżnianie
Page 22: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

7 varsquare:Square{

8 willSet{

9 triangle.sideLength=newValue.sideLength

10 }

11 }

12 init(size:Double,name:String){

13 square=Square(sideLength:size,name:name)

14 triangle=EquilateralTriangle(sideLength:size,name:

name)

15 }

16 }

17 vartriangleAndSquare=TriangleAndSquare(size:10,name:

"anothertestshape")

18 print(triangleAndSquare.square.sideLength)

19 //Prints"10.0"

20 print(triangleAndSquare.triangle.sideLength)

21 //Prints"10.0"

22 triangleAndSquare.square=Square(sideLength:50,name:

"largersquare")

23 print(triangleAndSquare.triangle.sideLength)

24 //Prints"50.0"

Whenworkingwithoptionalvalues,youcanwrite?beforeoperationslikemethods,properties,andsubscripting.Ifthevaluebeforethe?isnil,everythingafterthe?isignoredandthevalueofthewholeexpressionisnil.Otherwise,theoptionalvalueisunwrapped,andeverythingafterthe?actsontheunwrappedvalue.Inbothcases,thevalueofthewholeexpressionisanoptionalvalue.

1 letoptionalSquare:Square?=Square(sideLength:2.5,name:

"optionalsquare")

2 letsideLength=optionalSquare?.sideLength

MP
Wyróżnianie
MP
Wyróżnianie
Page 23: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

EnumerationsandStructures

Useenumtocreateanenumeration.Likeclassesandallothernamedtypes,enumerationscanhavemethodsassociatedwiththem.

1 enumRank:Int{

2 caseace=1

3 casetwo,three,four,five,six,seven,eight,nine,ten

4 casejack,queen,king

5

6 funcsimpleDescription()->String{

7 switchself{

8 case.ace:

9 return"ace"

10 case.jack:

11 return"jack"

12 case.queen:

13 return"queen"

14 case.king:

15 return"king"

16 default:

17 returnString(self.rawValue)

18 }

19 }

20 }

21 letace=Rank.ace

22 letaceRawValue=ace.rawValue

EXPER IMENT

WriteafunctionthatcomparestwoRankvaluesbycomparingtheirrawvalues.

Page 24: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Bydefault,Swiftassignstherawvaluesstartingatzeroandincrementingbyoneeachtime,butyoucanchangethisbehaviorbyexplicitlyspecifyingvalues.Intheexampleabove,Aceisexplicitlygivenarawvalueof1,andtherestoftherawvaluesareassignedinorder.Youcanalsousestringsorfloating-pointnumbersastherawtypeofanenumeration.UsetherawValuepropertytoaccesstherawvalueofanenumerationcase.

Usetheinit?(rawValue:)initializertomakeaninstanceofanenumerationfromarawvalue.ItreturnseithertheenumerationcasematchingtherawvalueornilifthereisnomatchingRank.

1 ifletconvertedRank=Rank(rawValue:3){

2 letthreeDescription=convertedRank.simpleDescription()

3 }

Thecasevaluesofanenumerationareactualvalues,notjustanotherwayofwritingtheirrawvalues.Infact,incaseswherethereisn’tameaningfulrawvalue,youdon’thavetoprovideone.

1 enumSuit{

2 casespades,hearts,diamonds,clubs

3

4 funcsimpleDescription()->String{

5 switchself{

6 case.spades:

7 return"spades"

8 case.hearts:

9 return"hearts"

10 case.diamonds:

11 return"diamonds"

12 case.clubs:

13 return"clubs"

14 }

Page 25: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

15 }

16 }

17 lethearts=Suit.hearts

18 letheartsDescription=hearts.simpleDescription()

EXPER IMENT

Addacolor()methodtoSuitthatreturns“black”forspadesandclubs,andreturns“red”forheartsanddiamonds.

Noticethetwowaysthattheheartscaseoftheenumerationisreferredtoabove:Whenassigningavaluetotheheartsconstant,theenumerationcaseSuit.heartsisreferredtobyitsfullnamebecausetheconstantdoesn’thaveanexplicittypespecified.Insidetheswitch,theenumerationcaseisreferredtobytheabbreviatedform.heartsbecausethevalueofselfisalreadyknowntobeasuit.Youcanusetheabbreviatedformanytimethevalue’stypeisalreadyknown.

Ifanenumerationhasrawvalues,thosevaluesaredeterminedaspartofthedeclaration,whichmeanseveryinstanceofaparticularenumerationcasealwayshasthesamerawvalue.Anotherchoiceforenumerationcasesistohavevaluesassociatedwiththecase—thesevaluesaredeterminedwhenyoumaketheinstance,andtheycanbedifferentforeachinstanceofanenumerationcase.Youcanthinkoftheassociatedvaluesasbehavinglikestoredpropertiesoftheenumerationcaseinstance.Forexample,considerthecaseofrequestingthesunriseandsunsettimesfromaserver.Theservereitherrespondswiththerequestedinformation,oritrespondswithadescriptionofwhatwentwrong.

1 enumServerResponse{

2 caseresult(String,String)

3 casefailure(String)

4 }

5

6 letsuccess=ServerResponse.result("6:00am","8:09pm")

7 letfailure=ServerResponse.failure("Outofcheese.")

Page 26: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8

9 switchsuccess{

10 caselet.result(sunrise,sunset):

11 print("Sunriseisat\(sunrise)andsunsetisat\

(sunset).")

12 caselet.failure(message):

13 print("Failure...\(message)")

14 }

15 //Prints"Sunriseisat6:00amandsunsetisat8:09pm."

EXPER IMENT

AddathirdcasetoServerResponseandtotheswitch.

NoticehowthesunriseandsunsettimesareextractedfromtheServerResponsevalueaspartofmatchingthevalueagainsttheswitchcases.

Usestructtocreateastructure.Structuressupportmanyofthesamebehaviorsasclasses,includingmethodsandinitializers.Oneofthemostimportantdifferencesbetweenstructuresandclassesisthatstructuresarealwayscopiedwhentheyarepassedaroundinyourcode,butclassesarepassedbyreference.

1 structCard{

2 varrank:Rank

3 varsuit:Suit

4 funcsimpleDescription()->String{

5 return"The\(rank.simpleDescription())of\

(suit.simpleDescription())"

6 }

7 }

8 letthreeOfSpades=Card(rank:.three,suit:.spades)

9 letthreeOfSpadesDescription=

Page 27: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

threeOfSpades.simpleDescription()

EXPER IMENT

Writeafunctionthatreturnsanarraycontainingafulldeckofcards,withonecardofeachcombinationofrankandsuit.

ProtocolsandExtensions

Useprotocoltodeclareaprotocol.

1 protocolExampleProtocol{

2 varsimpleDescription:String{get}

3 mutatingfuncadjust()

4 }

Classes,enumerations,andstructscanalladoptprotocols.

1 classSimpleClass:ExampleProtocol{

2 varsimpleDescription:String="Averysimpleclass."

3 varanotherProperty:Int=69105

4 funcadjust(){

5 simpleDescription+="Now100%adjusted."

6 }

7 }

8 vara=SimpleClass()

9 a.adjust()

10 letaDescription=a.simpleDescription

11

12 structSimpleStructure:ExampleProtocol{

13 varsimpleDescription:String="Asimplestructure"

Page 28: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

14 mutatingfuncadjust(){

15 simpleDescription+="(adjusted)"

16 }

17 }

18 varb=SimpleStructure()

19 b.adjust()

20 letbDescription=b.simpleDescription

EXPER IMENT

AddanotherrequirementtoExampleProtocol.WhatchangesdoyouneedtomaketoSimpleClassandSimpleStructuresothattheystillconformtotheprotocol?

NoticetheuseofthemutatingkeywordinthedeclarationofSimpleStructuretomarkamethodthatmodifiesthestructure.ThedeclarationofSimpleClassdoesn’tneedanyofitsmethodsmarkedasmutatingbecausemethodsonaclasscanalwaysmodifytheclass.

Useextensiontoaddfunctionalitytoanexistingtype,suchasnewmethodsandcomputedproperties.Youcanuseanextensiontoaddprotocolconformancetoatypethatisdeclaredelsewhere,oreventoatypethatyouimportedfromalibraryorframework.

1 extensionInt:ExampleProtocol{

2 varsimpleDescription:String{

3 return"Thenumber\(self)"

4 }

5 mutatingfuncadjust(){

6 self+=42

7 }

8 }

9 print(7.simpleDescription)

10 //Prints"Thenumber7"

Page 29: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

EXPER IMENT

WriteanextensionfortheDoubletypethataddsanabsoluteValueproperty.

Youcanuseaprotocolnamejustlikeanyothernamedtype—forexample,tocreateacollectionofobjectsthathavedifferenttypesbutthatallconformtoasingleprotocol.Whenyouworkwithvalueswhosetypeisaprotocoltype,methodsoutsidetheprotocoldefinitionarenotavailable.

1 letprotocolValue:ExampleProtocol=a

2 print(protocolValue.simpleDescription)

3 //Prints"Averysimpleclass.Now100%adjusted."

4 //print(protocolValue.anotherProperty)//Uncommenttosee

theerror

EventhoughthevariableprotocolValuehasaruntimetypeofSimpleClass,thecompilertreatsitasthegiventypeofExampleProtocol.Thismeansthatyoucan’taccidentallyaccessmethodsorpropertiesthattheclassimplementsinadditiontoitsprotocolconformance.

ErrorHandling

YourepresenterrorsusinganytypethatadoptstheErrorprotocol.

1 enumPrinterError:Error{

2 caseoutOfPaper

3 casenoToner

4 caseonFire

5 }

Usethrowtothrowanerrorandthrowstomarkafunctionthatcanthrowanerror.Ifyouthrowanerrorinafunction,thefunctionreturnsimmediatelyandthecodethatcalledthefunctionhandlestheerror.

Page 30: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 funcsend(job:Int,toPrinterprinterName:String)throws->

String{

2 ifprinterName=="NeverHasToner"{

3 throwPrinterError.noToner

4 }

5 return"Jobsent"

6 }

Thereareseveralwaystohandleerrors.Onewayistousedo-catch.Insidethedoblock,youmarkcodethatcanthrowanerrorbywritingtryinfrontofit.Insidethecatchblock,theerrorisautomaticallygiventhenameerrorunlessyougiveitadifferentname.

1 do{

2 letprinterResponse=trysend(job:1040,toPrinter:"Bi

Sheng")

3 print(printerResponse)

4 }catch{

5 print(error)

6 }

7 //Prints"Jobsent"

EXPER IMENT

Changetheprinternameto"NeverHasToner",sothatthesend(job:toPrinter:)functionthrowsanerror.

Youcanprovidemultiplecatchblocksthathandlespecificerrors.Youwriteapatternaftercatchjustasyoudoaftercaseinaswitch.

1 do{

2 letprinterResponse=trysend(job:1440,toPrinter:

"Gutenberg")

Page 31: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 print(printerResponse)

4 }catchPrinterError.onFire{

5 print("I'lljustputthisoverhere,withtherestofthe

fire.")

6 }catchletprinterErrorasPrinterError{

7 print("Printererror:\(printerError).")

8 }catch{

9 print(error)

10 }

11 //Prints"Jobsent"

EXPER IMENT

Addcodetothrowanerrorinsidethedoblock.Whatkindoferrordoyouneedtothrowsothattheerrorishandledbythefirstcatchblock?Whataboutthesecondandthirdblocks?

Anotherwaytohandleerrorsistousetry?toconverttheresulttoanoptional.Ifthefunctionthrowsanerror,thespecificerrorisdiscardedandtheresultisnil.Otherwise,theresultisanoptionalcontainingthevaluethatthefunctionreturned.

1 letprinterSuccess=try?send(job:1884,toPrinter:

"Mergenthaler")

2 letprinterFailure=try?send(job:1885,toPrinter:"NeverHas

Toner")

Usedefertowriteablockofcodethatisexecutedafterallothercodeinthefunction,justbeforethefunctionreturns.Thecodeisexecutedregardlessofwhetherthefunctionthrowsanerror.Youcanusedefertowritesetupandcleanupcodenexttoeachother,eventhoughtheyneedtobeexecutedatdifferenttimes.

1 varfridgeIsOpen=false

2 letfridgeContent=["milk","eggs","leftovers"]

Page 32: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3

4 funcfridgeContains(_food:String)->Bool{

5 fridgeIsOpen=true

6 defer{

7 fridgeIsOpen=false

8 }

9

10 letresult=fridgeContent.contains(food)

11 returnresult

12 }

13 fridgeContains("banana")

14 print(fridgeIsOpen)

15 //Prints"false"

Generics

Writeanameinsideanglebracketstomakeagenericfunctionortype.

1 funcmakeArray<Item>(repeatingitem:Item,numberOfTimes:Int)

->[Item]{

2 varresult=[Item]()

3 for_in0..<numberOfTimes{

4 result.append(item)

5 }

6 returnresult

7 }

8 makeArray(repeating:"knock",numberOfTimes:4)

Youcanmakegenericformsoffunctionsandmethods,aswellasclasses,

Page 33: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

enumerations,andstructures.

1 //ReimplementtheSwiftstandardlibrary'soptionaltype

2 enumOptionalValue<Wrapped>{

3 casenone

4 casesome(Wrapped)

5 }

6 varpossibleInteger:OptionalValue<Int>=.none

7 possibleInteger=.some(100)

Usewhererightbeforethebodytospecifyalistofrequirements—forexample,torequirethetypetoimplementaprotocol,torequiretwotypestobethesame,ortorequireaclasstohaveaparticularsuperclass.

1 funcanyCommonElements<T:Sequence,U:Sequence>(_lhs:T,_

rhs:U)->Bool

2 whereT.Element:Equatable,T.Element==U.Element

3 {

4 forlhsIteminlhs{

5 forrhsIteminrhs{

6 iflhsItem==rhsItem{

7 returntrue

8 }

9 }

10 }

11 returnfalse

12 }

13 anyCommonElements([1,2,3],[3])

EXPER IMENT

ModifytheanyCommonElements(_:_:)functiontomakeafunctionthatreturnsanarrayoftheelementsthatanytwosequenceshaveincommon.

Page 34: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Writing<T:Equatable>isthesameaswriting<T>...whereT:Equatable.

Page 35: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

LanguageGuide

Page 36: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheBasics

SwiftisanewprogramminglanguageforiOS,macOS,watchOS,andtvOSappdevelopment.Nonetheless,manypartsofSwiftwillbefamiliarfromyourexperienceofdevelopinginCandObjective-C.

SwiftprovidesitsownversionsofallfundamentalCandObjective-Ctypes,includingIntforintegers,DoubleandFloatforfloating-pointvalues,BoolforBooleanvalues,andStringfortextualdata.Swiftalsoprovidespowerfulversionsofthethreeprimarycollectiontypes,Array,Set,andDictionary,asdescribedinCollectionTypes.

LikeC,Swiftusesvariablestostoreandrefertovaluesbyanidentifyingname.Swiftalsomakesextensiveuseofvariableswhosevaluescan’tbechanged.Theseareknownasconstants,andaremuchmorepowerfulthanconstantsinC.ConstantsareusedthroughoutSwifttomakecodesaferandclearerinintentwhenyouworkwithvaluesthatdon’tneedtochange.

Inadditiontofamiliartypes,SwiftintroducesadvancedtypesnotfoundinObjective-C,suchastuples.Tuplesenableyoutocreateandpassaroundgroupingsofvalues.Youcanuseatupletoreturnmultiplevaluesfromafunctionasasinglecompoundvalue.

Swiftalsointroducesoptionaltypes,whichhandletheabsenceofavalue.Optionalssayeither“thereisavalue,anditequalsx”or“thereisn’tavalueatall”.UsingoptionalsissimilartousingnilwithpointersinObjective-C,buttheyworkforanytype,notjustclasses.NotonlyareoptionalssaferandmoreexpressivethannilpointersinObjective-C,they’reattheheartofmanyofSwift’smostpowerfulfeatures.

Swiftisatype-safelanguage,whichmeansthelanguagehelpsyoutobeclearaboutthetypesofvaluesyourcodecanworkwith.IfpartofyourcoderequiresaString,typesafetypreventsyoufrompassingitanIntbymistake.Likewise,typesafetypreventsyoufromaccidentallypassinganoptionalStringtoapieceofcodethatrequiresanon-optionalString.Typesafetyhelpsyoucatchandfixerrorsasearlyaspossibleinthedevelopmentprocess.

Page 37: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ConstantsandVariables

Constantsandvariablesassociateaname(suchasmaximumNumberOfLoginAttemptsorwelcomeMessage)withavalueofaparticulartype(suchasthenumber10orthestring"Hello").Thevalueofaconstantcan’tbechangedonceit’sset,whereasavariablecanbesettoadifferentvalueinthefuture.

DeclaringConstantsandVariablesConstantsandvariablesmustbedeclaredbeforethey’reused.Youdeclareconstantswiththeletkeywordandvariableswiththevarkeyword.Here’sanexampleofhowconstantsandvariablescanbeusedtotrackthenumberofloginattemptsauserhasmade:

1 letmaximumNumberOfLoginAttempts=10

2 varcurrentLoginAttempt=0

Thiscodecanbereadas:

“DeclareanewconstantcalledmaximumNumberOfLoginAttempts,andgiveitavalueof10.Then,declareanewvariablecalledcurrentLoginAttempt,andgiveitaninitialvalueof0.”

Inthisexample,themaximumnumberofallowedloginattemptsisdeclaredasaconstant,becausethemaximumvalueneverchanges.Thecurrentloginattemptcounterisdeclaredasavariable,becausethisvaluemustbeincrementedaftereachfailedloginattempt.

Youcandeclaremultipleconstantsormultiplevariablesonasingleline,separatedbycommas:

varx=0.0,y=0.0,z=0.0

NOTE

Ifastoredvalueinyourcodewon’tchange,alwaysdeclareitasaconstantwiththeletkeyword.

Page 38: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Usevariablesonlyforstoringvaluesthatneedtobeabletochange.

TypeAnnotationsYoucanprovideatypeannotationwhenyoudeclareaconstantorvariable,tobeclearaboutthekindofvaluestheconstantorvariablecanstore.Writeatypeannotationbyplacingacolonaftertheconstantorvariablename,followedbyaspace,followedbythenameofthetypetouse.

ThisexampleprovidesatypeannotationforavariablecalledwelcomeMessage,toindicatethatthevariablecanstoreStringvalues:

varwelcomeMessage:String

Thecoloninthedeclarationmeans“…oftype…,”sothecodeabovecanbereadas:

“DeclareavariablecalledwelcomeMessagethatisoftypeString.”

Thephrase“oftypeString”means“canstoreanyStringvalue.”Thinkofitasmeaning“thetypeofthing”(or“thekindofthing”)thatcanbestored.

ThewelcomeMessagevariablecannowbesettoanystringvaluewithouterror:

welcomeMessage="Hello"

Youcandefinemultiplerelatedvariablesofthesametypeonasingleline,separatedbycommas,withasingletypeannotationafterthefinalvariablename:

varred,green,blue:Double

NOTE

It’srarethatyouneedtowritetypeannotationsinpractice.Ifyouprovideaninitialvalueforaconstantorvariableatthepointthatit’sdefined,Swiftcanalmostalwaysinferthetypetobeusedforthatconstantorvariable,asdescribedinTypeSafetyandTypeInference.InthewelcomeMessageexampleabove,noinitialvalueisprovided,andsothetypeofthewelcomeMessagevariableis

Page 39: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

specifiedwithatypeannotationratherthanbeinginferredfromaninitialvalue.

NamingConstantsandVariablesConstantandvariablenamescancontainalmostanycharacter,includingUnicodecharacters:

1 letπ=3.14159

2 let =""

3 let ="dogcow"

Constantandvariablenamescan’tcontainwhitespacecharacters,mathematicalsymbols,arrows,private-useUnicodescalarvalues,orline-andbox-drawingcharacters.Norcantheybeginwithanumber,althoughnumbersmaybeincludedelsewherewithinthename.

Onceyou’vedeclaredaconstantorvariableofacertaintype,youcan’tdeclareitagainwiththesamename,orchangeittostorevaluesofadifferenttype.Norcanyouchangeaconstantintoavariableoravariableintoaconstant.

NOTE

IfyouneedtogiveaconstantorvariablethesamenameasareservedSwiftkeyword,surroundthekeywordwithbackticks(`)whenusingitasaname.However,avoidusingkeywordsasnamesunlessyouhaveabsolutelynochoice.

Youcanchangethevalueofanexistingvariabletoanothervalueofacompatibletype.Inthisexample,thevalueoffriendlyWelcomeischangedfrom"Hello!"to"Bonjour!":

1 varfriendlyWelcome="Hello!"

2 friendlyWelcome="Bonjour!"

3 //friendlyWelcomeisnow"Bonjour!"

Unlikeavariable,thevalueofaconstantcan’tbechangedafterit’sset.

Page 40: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Attemptingtodosoisreportedasanerrorwhenyourcodeiscompiled:

1 letlanguageName="Swift"

2 languageName="Swift++"

3 //Thisisacompile-timeerror:languageNamecannotbe

changed.

PrintingConstantsandVariablesYoucanprintthecurrentvalueofaconstantorvariablewiththeprint(_:separator:terminator:)function:

1 print(friendlyWelcome)

2 //Prints"Bonjour!"

Theprint(_:separator:terminator:)functionisaglobalfunctionthatprintsoneormorevaluestoanappropriateoutput.InXcode,forexample,theprint(_:separator:terminator:)functionprintsitsoutputinXcode’s“console”pane.Theseparatorandterminatorparameterhavedefaultvalues,soyoucanomitthemwhenyoucallthisfunction.Bydefault,thefunctionterminatesthelineitprintsbyaddingalinebreak.Toprintavaluewithoutalinebreakafterit,passanemptystringastheterminator—forexample,print(someValue,terminator:"").Forinformationaboutparameterswithdefaultvalues,seeDefaultParameterValues.

Swiftusesstringinterpolationtoincludethenameofaconstantorvariableasaplaceholderinalongerstring,andtopromptSwifttoreplaceitwiththecurrentvalueofthatconstantorvariable.Wrapthenameinparenthesesandescapeitwithabackslashbeforetheopeningparenthesis:

1 print("ThecurrentvalueoffriendlyWelcomeis\

(friendlyWelcome)")

2 //Prints"ThecurrentvalueoffriendlyWelcomeisBonjour!"

Page 41: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

AlloptionsyoucanusewithstringinterpolationaredescribedinStringInterpolation.

Comments

Usecommentstoincludenonexecutabletextinyourcode,asanoteorremindertoyourself.CommentsareignoredbytheSwiftcompilerwhenyourcodeiscompiled.

CommentsinSwiftareverysimilartocommentsinC.Single-linecommentsbeginwithtwoforward-slashes(//):

//Thisisacomment.

Multilinecommentsstartwithaforward-slashfollowedbyanasterisk(/*)andendwithanasteriskfollowedbyaforward-slash(*/):

1 /*Thisisalsoacomment

2 butiswrittenovermultiplelines.*/

UnlikemultilinecommentsinC,multilinecommentsinSwiftcanbenestedinsideothermultilinecomments.Youwritenestedcommentsbystartingamultilinecommentblockandthenstartingasecondmultilinecommentwithinthefirstblock.Thesecondblockisthenclosed,followedbythefirstblock:

1 /*Thisisthestartofthefirstmultilinecomment.

2 /*Thisisthesecond,nestedmultilinecomment.*/

3 Thisistheendofthefirstmultilinecomment.*/

Nestedmultilinecommentsenableyoutocommentoutlargeblocksofcodequicklyandeasily,evenifthecodealreadycontainsmultilinecomments.

Page 42: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Semicolons

Unlikemanyotherlanguages,Swiftdoesn’trequireyoutowriteasemicolon(;)aftereachstatementinyourcode,althoughyoucandosoifyouwish.However,semicolonsarerequiredifyouwanttowritemultipleseparatestatementsonasingleline:

1 letcat=" ";print(cat)

2 //Prints" "

Integers

Integersarewholenumberswithnofractionalcomponent,suchas42and-23.Integersareeithersigned(positive,zero,ornegative)orunsigned(positiveorzero).

Swiftprovidessignedandunsignedintegersin8,16,32,and64bitforms.TheseintegersfollowanamingconventionsimilartoC,inthatan8-bitunsignedintegerisoftypeUInt8,anda32-bitsignedintegerisoftypeInt32.LikealltypesinSwift,theseintegertypeshavecapitalizednames.

IntegerBoundsYoucanaccesstheminimumandmaximumvaluesofeachintegertypewithitsminandmaxproperties:

1 letminValue=UInt8.min//minValueisequalto0,andisof

typeUInt8

2 letmaxValue=UInt8.max//maxValueisequalto255,andis

oftypeUInt8

Thevaluesofthesepropertiesareoftheappropriate-sizednumbertype(suchasUInt8intheexampleabove)andcanthereforebeusedinexpressionsalongside

Page 43: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

othervaluesofthesametype.

IntInmostcases,youdon’tneedtopickaspecificsizeofintegertouseinyourcode.Swiftprovidesanadditionalintegertype,Int,whichhasthesamesizeasthecurrentplatform’snativewordsize:

Ona32-bitplatform,IntisthesamesizeasInt32.

Ona64-bitplatform,IntisthesamesizeasInt64.

Unlessyouneedtoworkwithaspecificsizeofinteger,alwaysuseIntforintegervaluesinyourcode.Thisaidscodeconsistencyandinteroperability.Evenon32-bitplatforms,Intcanstoreanyvaluebetween-2,147,483,648and2,147,483,647,andislargeenoughformanyintegerranges.

UIntSwiftalsoprovidesanunsignedintegertype,UInt,whichhasthesamesizeasthecurrentplatform’snativewordsize:

Ona32-bitplatform,UIntisthesamesizeasUInt32.

Ona64-bitplatform,UIntisthesamesizeasUInt64.

NOTE

UseUIntonlywhenyouspecificallyneedanunsignedintegertypewiththesamesizeastheplatform’snativewordsize.Ifthisisn’tthecase,Intispreferred,evenwhenthevaluestobestoredareknowntobenonnegative.AconsistentuseofIntforintegervaluesaidscodeinteroperability,avoidstheneedtoconvertbetweendifferentnumbertypes,andmatchesintegertypeinference,asdescribedinTypeSafetyandTypeInference.

Floating-PointNumbers

Page 44: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Floating-pointnumbersarenumberswithafractionalcomponent,suchas3.14159,0.1,and-273.15.

Floating-pointtypescanrepresentamuchwiderrangeofvaluesthanintegertypes,andcanstorenumbersthataremuchlargerorsmallerthancanbestoredinanInt.Swiftprovidestwosignedfloating-pointnumbertypes:

Doublerepresentsa64-bitfloating-pointnumber.

Floatrepresentsa32-bitfloating-pointnumber.

NOTE

Doublehasaprecisionofatleast15decimaldigits,whereastheprecisionofFloatcanbeaslittleas6decimaldigits.Theappropriatefloating-pointtypetousedependsonthenatureandrangeofvaluesyouneedtoworkwithinyourcode.Insituationswhereeithertypewouldbeappropriate,Doubleispreferred.

TypeSafetyandTypeInference

Swiftisatype-safelanguage.Atypesafelanguageencouragesyoutobeclearaboutthetypesofvaluesyourcodecanworkwith.IfpartofyourcoderequiresaString,youcan’tpassitanIntbymistake.

BecauseSwiftistypesafe,itperformstypecheckswhencompilingyourcodeandflagsanymismatchedtypesaserrors.Thisenablesyoutocatchandfixerrorsasearlyaspossibleinthedevelopmentprocess.

Type-checkinghelpsyouavoiderrorswhenyou’reworkingwithdifferenttypesofvalues.However,thisdoesn’tmeanthatyouhavetospecifythetypeofeveryconstantandvariablethatyoudeclare.Ifyoudon’tspecifythetypeofvalueyouneed,Swiftusestypeinferencetoworkouttheappropriatetype.Typeinferenceenablesacompilertodeducethetypeofaparticularexpressionautomaticallywhenitcompilesyourcode,simplybyexaminingthevaluesyouprovide.

Becauseoftypeinference,SwiftrequiresfarfewertypedeclarationsthanlanguagessuchasCorObjective-C.Constantsandvariablesarestillexplicitly

Page 45: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

typed,butmuchoftheworkofspecifyingtheirtypeisdoneforyou.

Typeinferenceisparticularlyusefulwhenyoudeclareaconstantorvariablewithaninitialvalue.Thisisoftendonebyassigningaliteralvalue(orliteral)totheconstantorvariableatthepointthatyoudeclareit.(Aliteralvalueisavaluethatappearsdirectlyinyoursourcecode,suchas42and3.14159intheexamplesbelow.)

Forexample,ifyouassignaliteralvalueof42toanewconstantwithoutsayingwhattypeitis,SwiftinfersthatyouwanttheconstanttobeanInt,becauseyouhaveinitializeditwithanumberthatlookslikeaninteger:

1 letmeaningOfLife=42

2 //meaningOfLifeisinferredtobeoftypeInt

Likewise,ifyoudon’tspecifyatypeforafloating-pointliteral,SwiftinfersthatyouwanttocreateaDouble:

1 letpi=3.14159

2 //piisinferredtobeoftypeDouble

SwiftalwayschoosesDouble(ratherthanFloat)wheninferringthetypeoffloating-pointnumbers.

Ifyoucombineintegerandfloating-pointliteralsinanexpression,atypeofDoublewillbeinferredfromthecontext:

1 letanotherPi=3+0.14159

2 //anotherPiisalsoinferredtobeoftypeDouble

Theliteralvalueof3hasnoexplicittypeinandofitself,andsoanappropriateoutputtypeofDoubleisinferredfromthepresenceofafloating-pointliteralaspartoftheaddition.

Page 46: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NumericLiterals

Integerliteralscanbewrittenas:

Adecimalnumber,withnoprefix

Abinarynumber,witha0bprefix

Anoctalnumber,witha0oprefix

Ahexadecimalnumber,witha0xprefix

Alloftheseintegerliteralshaveadecimalvalueof17:

1 letdecimalInteger=17

2 letbinaryInteger=0b10001//17inbinarynotation

3 letoctalInteger=0o21//17inoctalnotation

4 lethexadecimalInteger=0x11//17inhexadecimalnotation

Floating-pointliteralscanbedecimal(withnoprefix),orhexadecimal(witha0xprefix).Theymustalwayshaveanumber(orhexadecimalnumber)onbothsidesofthedecimalpoint.Decimalfloatscanalsohaveanoptionalexponent,indicatedbyanuppercaseorlowercasee;hexadecimalfloatsmusthaveanexponent,indicatedbyanuppercaseorlowercasep.

Fordecimalnumberswithanexponentofexp,thebasenumberismultipliedby10exp:

1.25e2means1.25x102,or125.0.

1.25e-2means1.25x10-2,or0.0125.

Forhexadecimalnumberswithanexponentofexp,thebasenumberismultipliedby2exp:

0xFp2means15x22,or60.0.

Page 47: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

0xFp-2means15x2-2,or3.75.

Allofthesefloating-pointliteralshaveadecimalvalueof12.1875:

1 letdecimalDouble=12.1875

2 letexponentDouble=1.21875e1

3 lethexadecimalDouble=0xC.3p0

Numericliteralscancontainextraformattingtomakethemeasiertoread.Bothintegersandfloatscanbepaddedwithextrazerosandcancontainunderscorestohelpwithreadability.Neithertypeofformattingaffectstheunderlyingvalueoftheliteral:

1 letpaddedDouble=000123.456

2 letoneMillion=1_000_000

3 letjustOverOneMillion=1_000_000.000_000_1

NumericTypeConversion

UsetheInttypeforallgeneral-purposeintegerconstantsandvariablesinyourcode,evenifthey’reknowntobenonnegative.Usingthedefaultintegertypeineverydaysituationsmeansthatintegerconstantsandvariablesareimmediatelyinteroperableinyourcodeandwillmatchtheinferredtypeforintegerliteralvalues.

Useotherintegertypesonlywhenthey’respecificallyneededforthetaskathand,becauseofexplicitlysizeddatafromanexternalsource,orforperformance,memoryusage,orothernecessaryoptimization.Usingexplicitlysizedtypesinthesesituationshelpstocatchanyaccidentalvalueoverflowsandimplicitlydocumentsthenatureofthedatabeingused.

IntegerConversion

Page 48: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Therangeofnumbersthatcanbestoredinanintegerconstantorvariableisdifferentforeachnumerictype.AnInt8constantorvariablecanstorenumbersbetween-128and127,whereasaUInt8constantorvariablecanstorenumbersbetween0and255.Anumberthatwon’tfitintoaconstantorvariableofasizedintegertypeisreportedasanerrorwhenyourcodeiscompiled:

1 letcannotBeNegative:UInt8=-1

2 //UInt8cannotstorenegativenumbers,andsothiswillreport

anerror

3 lettooBig:Int8=Int8.max+1

4 //Int8cannotstoreanumberlargerthanitsmaximumvalue,

5 //andsothiswillalsoreportanerror

Becauseeachnumerictypecanstoreadifferentrangeofvalues,youmustoptintonumerictypeconversiononacase-by-casebasis.Thisopt-inapproachpreventshiddenconversionerrorsandhelpsmaketypeconversionintentionsexplicitinyourcode.

Toconvertonespecificnumbertypetoanother,youinitializeanewnumberofthedesiredtypewiththeexistingvalue.Intheexamplebelow,theconstanttwoThousandisoftypeUInt16,whereastheconstantoneisoftypeUInt8.Theycan’tbeaddedtogetherdirectly,becausethey’renotofthesametype.Instead,thisexamplecallsUInt16(one)tocreateanewUInt16initializedwiththevalueofone,andusesthisvalueinplaceoftheoriginal:

1 lettwoThousand:UInt16=2_000

2 letone:UInt8=1

3 lettwoThousandAndOne=twoThousand+UInt16(one)

BecausebothsidesoftheadditionarenowoftypeUInt16,theadditionisallowed.Theoutputconstant(twoThousandAndOne)isinferredtobeoftypeUInt16,becauseit’sthesumoftwoUInt16values.

SomeType(ofInitialValue)isthedefaultwaytocalltheinitializerofaSwifttypeandpassinaninitialvalue.Behindthescenes,UInt16hasaninitializerthat

Page 49: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

acceptsaUInt8value,andsothisinitializerisusedtomakeanewUInt16fromanexistingUInt8.Youcan’tpassinanytypehere,however—ithastobeatypeforwhichUInt16providesaninitializer.Extendingexistingtypestoprovideinitializersthatacceptnewtypes(includingyourowntypedefinitions)iscoveredinExtensions.

IntegerandFloating-PointConversionConversionsbetweenintegerandfloating-pointnumerictypesmustbemadeexplicit:

1 letthree=3

2 letpointOneFourOneFiveNine=0.14159

3 letpi=Double(three)+pointOneFourOneFiveNine

4 //piequals3.14159,andisinferredtobeoftypeDouble

Here,thevalueoftheconstantthreeisusedtocreateanewvalueoftypeDouble,sothatbothsidesoftheadditionareofthesametype.Withoutthisconversioninplace,theadditionwouldnotbeallowed.

Floating-pointtointegerconversionmustalsobemadeexplicit.AnintegertypecanbeinitializedwithaDoubleorFloatvalue:

1 letintegerPi=Int(pi)

2 //integerPiequals3,andisinferredtobeoftypeInt

Floating-pointvaluesarealwaystruncatedwhenusedtoinitializeanewintegervalueinthisway.Thismeansthat4.75becomes4,and-3.9becomes-3.

NOTE

Therulesforcombiningnumericconstantsandvariablesaredifferentfromtherulesfornumericliterals.Theliteralvalue3canbeaddeddirectlytotheliteralvalue0.14159,becausenumberliteralsdon’thaveanexplicittypeinandofthemselves.Theirtypeisinferredonlyatthepointthatthey’reevaluatedbythecompiler.

Page 50: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TypeAliases

Typealiasesdefineanalternativenameforanexistingtype.Youdefinetypealiaseswiththetypealiaskeyword.

Typealiasesareusefulwhenyouwanttorefertoanexistingtypebyanamethatiscontextuallymoreappropriate,suchaswhenworkingwithdataofaspecificsizefromanexternalsource:

typealiasAudioSample=UInt16

Onceyoudefineatypealias,youcanusethealiasanywhereyoumightusetheoriginalname:

1 varmaxAmplitudeFound=AudioSample.min

2 //maxAmplitudeFoundisnow0

Here,AudioSampleisdefinedasanaliasforUInt16.Becauseit’sanalias,thecalltoAudioSample.minactuallycallsUInt16.min,whichprovidesaninitialvalueof0forthemaxAmplitudeFoundvariable.

Booleans

SwifthasabasicBooleantype,calledBool.Booleanvaluesarereferredtoaslogical,becausetheycanonlyeverbetrueorfalse.SwiftprovidestwoBooleanconstantvalues,trueandfalse:

1 letorangesAreOrange=true

2 letturnipsAreDelicious=false

ThetypesoforangesAreOrangeandturnipsAreDelicioushavebeeninferredasBoolfromthefactthattheywereinitializedwithBooleanliteralvalues.AswithIntandDoubleabove,youdon’tneedtodeclareconstantsorvariablesasBoolifyousetthemtotrueorfalseassoonasyoucreatethem.Typeinferencehelps

Page 51: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

makeSwiftcodemoreconciseandreadablewhenitinitializesconstantsorvariableswithothervalueswhosetypeisalreadyknown.

Booleanvaluesareparticularlyusefulwhenyouworkwithconditionalstatementssuchastheifstatement:

1 ifturnipsAreDelicious{

2 print("Mmm,tastyturnips!")

3 }else{

4 print("Eww,turnipsarehorrible.")

5 }

6 //Prints"Eww,turnipsarehorrible."

ConditionalstatementssuchastheifstatementarecoveredinmoredetailinControlFlow.

Swift’stypesafetypreventsnon-BooleanvaluesfrombeingsubstitutedforBool.Thefollowingexamplereportsacompile-timeerror:

1 leti=1

2 ifi{

3 //thisexamplewillnotcompile,andwillreportanerror

4 }

However,thealternativeexamplebelowisvalid:

1 leti=1

2 ifi==1{

3 //thisexamplewillcompilesuccessfully

4 }

Theresultofthei==1comparisonisoftypeBool,andsothissecondexamplepassesthetype-check.Comparisonslikei==1arediscussedinBasicOperators.

Page 52: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AswithotherexamplesoftypesafetyinSwift,thisapproachavoidsaccidentalerrorsandensuresthattheintentionofaparticularsectionofcodeisalwaysclear.

Tuples

Tuplesgroupmultiplevaluesintoasinglecompoundvalue.Thevalueswithinatuplecanbeofanytypeanddon’thavetobeofthesametypeaseachother.

Inthisexample,(404,"NotFound")isatuplethatdescribesanHTTPstatuscode.AnHTTPstatuscodeisaspecialvaluereturnedbyawebserverwheneveryourequestawebpage.Astatuscodeof404NotFoundisreturnedifyourequestawebpagethatdoesn’texist.

1 lethttp404Error=(404,"NotFound")

2 //http404Errorisoftype(Int,String),andequals(404,"Not

Found")

The(404,"NotFound")tuplegroupstogetheranIntandaStringtogivetheHTTPstatuscodetwoseparatevalues:anumberandahuman-readabledescription.Itcanbedescribedas“atupleoftype(Int,String)”.

Youcancreatetuplesfromanypermutationoftypes,andtheycancontainasmanydifferenttypesasyoulike.There’snothingstoppingyoufromhavingatupleoftype(Int,Int,Int),or(String,Bool),orindeedanyotherpermutationyourequire.

Youcandecomposeatuple’scontentsintoseparateconstantsorvariables,whichyouthenaccessasusual:

1 let(statusCode,statusMessage)=http404Error

2 print("Thestatuscodeis\(statusCode)")

3 //Prints"Thestatuscodeis404"

4 print("Thestatusmessageis\(statusMessage)")

Page 53: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 //Prints"ThestatusmessageisNotFound"

Ifyouonlyneedsomeofthetuple’svalues,ignorepartsofthetuplewithanunderscore(_)whenyoudecomposethetuple:

1 let(justTheStatusCode,_)=http404Error

2 print("Thestatuscodeis\(justTheStatusCode)")

3 //Prints"Thestatuscodeis404"

Alternatively,accesstheindividualelementvaluesinatupleusingindexnumbersstartingatzero:

1 print("Thestatuscodeis\(http404Error.0)")

2 //Prints"Thestatuscodeis404"

3 print("Thestatusmessageis\(http404Error.1)")

4 //Prints"ThestatusmessageisNotFound"

Youcannametheindividualelementsinatuplewhenthetupleisdefined:

lethttp200Status=(statusCode:200,description:"OK")

Ifyounametheelementsinatuple,youcanusetheelementnamestoaccessthevaluesofthoseelements:

1 print("Thestatuscodeis\(http200Status.statusCode)")

2 //Prints"Thestatuscodeis200"

3 print("Thestatusmessageis\(http200Status.description)")

4 //Prints"ThestatusmessageisOK"

Tuplesareparticularlyusefulasthereturnvaluesoffunctions.Afunctionthattriestoretrieveawebpagemightreturnthe(Int,String)tupletypetodescribethesuccessorfailureofthepageretrieval.Byreturningatuplewithtwodistinctvalues,eachofadifferenttype,thefunctionprovidesmoreusefulinformationaboutitsoutcomethanifitcouldonlyreturnasinglevalueofasingletype.For

Page 54: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

moreinformation,seeFunctionswithMultipleReturnValues.

NOTE

Tuplesareusefulforsimplegroupsofrelatedvalues.They’renotsuitedtothecreationofcomplexdatastructures.Ifyourdatastructureislikelytobemorecomplex,modelitasaclassorstructure,ratherthanasatuple.Formoreinformation,seeStructuresandClasses.

Optionals

Youuseoptionalsinsituationswhereavaluemaybeabsent.Anoptionalrepresentstwopossibilities:Eitherthereisavalue,andyoucanunwraptheoptionaltoaccessthatvalue,orthereisn’tavalueatall.

NOTE

Theconceptofoptionalsdoesn’texistinCorObjective-C.ThenearestthinginObjective-Cistheabilitytoreturnnilfromamethodthatwouldotherwisereturnanobject,withnilmeaning“theabsenceofavalidobject.”However,thisonlyworksforobjects—itdoesn’tworkforstructures,basicCtypes,orenumerationvalues.Forthesetypes,Objective-Cmethodstypicallyreturnaspecialvalue(suchasNSNotFound)toindicatetheabsenceofavalue.Thisapproachassumesthatthemethod’scallerknowsthere’saspecialvaluetotestagainstandrememberstocheckforit.Swift’soptionalsletyouindicatetheabsenceofavalueforanytypeatall,withouttheneedforspecialconstants.

Here’sanexampleofhowoptionalscanbeusedtocopewiththeabsenceofavalue.Swift’sInttypehasaninitializerwhichtriestoconvertaStringvalueintoanIntvalue.However,noteverystringcanbeconvertedintoaninteger.Thestring"123"canbeconvertedintothenumericvalue123,butthestring"hello,world"doesn’thaveanobviousnumericvaluetoconvertto.

TheexamplebelowusestheinitializertotrytoconvertaStringintoanInt:

1 letpossibleNumber="123"

2 letconvertedNumber=Int(possibleNumber)

3 //convertedNumberisinferredtobeoftype"Int?",or

"optionalInt"

Page 55: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Becausetheinitializermightfail,itreturnsanoptionalInt,ratherthananInt.AnoptionalIntiswrittenasInt?,notInt.Thequestionmarkindicatesthatthevalueitcontainsisoptional,meaningthatitmightcontainsomeIntvalue,oritmightcontainnovalueatall.(Itcan’tcontainanythingelse,suchasaBoolvalueoraStringvalue.It’seitheranInt,orit’snothingatall.)

nilYousetanoptionalvariabletoavaluelessstatebyassigningitthespecialvaluenil:

1 varserverResponseCode:Int?=404

2 //serverResponseCodecontainsanactualIntvalueof404

3 serverResponseCode=nil

4 //serverResponseCodenowcontainsnovalue

NOTE

Youcan’tusenilwithnon-optionalconstantsandvariables.Ifaconstantorvariableinyourcodeneedstoworkwiththeabsenceofavalueundercertainconditions,alwaysdeclareitasanoptionalvalueoftheappropriatetype.

Ifyoudefineanoptionalvariablewithoutprovidingadefaultvalue,thevariableisautomaticallysettonilforyou:

1 varsurveyAnswer:String?

2 //surveyAnswerisautomaticallysettonil

NOTE

Swift’snilisn’tthesameasnilinObjective-C.InObjective-C,nilisapointertoanonexistentobject.InSwift,nilisn’tapointer—it’stheabsenceofavalueofacertaintype.Optionalsofanytypecanbesettonil,notjustobjecttypes.

Page 56: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

IfStatementsandForcedUnwrappingYoucanuseanifstatementtofindoutwhetheranoptionalcontainsavaluebycomparingtheoptionalagainstnil.Youperformthiscomparisonwiththe“equalto”operator(==)orthe“notequalto”operator(!=).

Ifanoptionalhasavalue,it’sconsideredtobe“notequalto”nil:

1 ifconvertedNumber!=nil{

2 print("convertedNumbercontainssomeintegervalue.")

3 }

4 //Prints"convertedNumbercontainssomeintegervalue."

Onceyou’resurethattheoptionaldoescontainavalue,youcanaccessitsunderlyingvaluebyaddinganexclamationmark(!)totheendoftheoptional’sname.Theexclamationmarkeffectivelysays,“Iknowthatthisoptionaldefinitelyhasavalue;pleaseuseit.”Thisisknownasforcedunwrappingoftheoptional’svalue:

1 ifconvertedNumber!=nil{

2 print("convertedNumberhasanintegervalueof\

(convertedNumber!).")

3 }

4 //Prints"convertedNumberhasanintegervalueof123."

Formoreabouttheifstatement,seeControlFlow.

NOTE

Tryingtouse!toaccessanonexistentoptionalvaluetriggersaruntimeerror.Alwaysmakesurethatanoptionalcontainsanon-nilvaluebeforeusing!toforce-unwrapitsvalue.

OptionalBindingYouuseoptionalbindingtofindoutwhetheranoptionalcontainsavalue,andif

Page 57: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

so,tomakethatvalueavailableasatemporaryconstantorvariable.Optionalbindingcanbeusedwithifandwhilestatementstocheckforavalueinsideanoptional,andtoextractthatvalueintoaconstantorvariable,aspartofasingleaction.ifandwhilestatementsaredescribedinmoredetailinControlFlow.

Writeanoptionalbindingforanifstatementasfollows:

iflet constantName = someOptional {

statements

}

YoucanrewritethepossibleNumberexamplefromtheOptionalssectiontouseoptionalbindingratherthanforcedunwrapping:

1 ifletactualNumber=Int(possibleNumber){

2 print("Thestring\"\(possibleNumber)\"hasaninteger

valueof\(actualNumber)")

3 }else{

4 print("Thestring\"\(possibleNumber)\"couldnotbe

convertedtoaninteger")

5 }

6 //Prints"Thestring"123"hasanintegervalueof123"

Thiscodecanbereadas:

“IftheoptionalIntreturnedbyInt(possibleNumber)containsavalue,setanewconstantcalledactualNumbertothevaluecontainedintheoptional.”

Iftheconversionissuccessful,theactualNumberconstantbecomesavailableforusewithinthefirstbranchoftheifstatement.Ithasalreadybeeninitializedwiththevaluecontainedwithintheoptional,andsothere’snoneedtousethe!suffixtoaccessitsvalue.Inthisexample,actualNumberissimplyusedtoprinttheresultoftheconversion.

Youcanusebothconstantsandvariableswithoptionalbinding.Ifyouwantedto

Page 58: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

manipulatethevalueofactualNumberwithinthefirstbranchoftheifstatement,youcouldwriteifvaractualNumberinstead,andthevaluecontainedwithintheoptionalwouldbemadeavailableasavariableratherthanaconstant.

YoucanincludeasmanyoptionalbindingsandBooleanconditionsinasingleifstatementasyouneedto,separatedbycommas.IfanyofthevaluesintheoptionalbindingsareniloranyBooleanconditionevaluatestofalse,thewholeifstatement’sconditionisconsideredtobefalse.Thefollowingifstatementsareequivalent:

1 ifletfirstNumber=Int("4"),letsecondNumber=Int("42"),

firstNumber<secondNumber&&secondNumber<100{

2 print("\(firstNumber)<\(secondNumber)<100")

3 }

4 //Prints"4<42<100"

5

6 ifletfirstNumber=Int("4"){

7 ifletsecondNumber=Int("42"){

8 iffirstNumber<secondNumber&&secondNumber<100{

9 print("\(firstNumber)<\(secondNumber)<100")

10 }

11 }

12 }

13 //Prints"4<42<100"

NOTE

Constantsandvariablescreatedwithoptionalbindinginanifstatementareavailableonlywithinthebodyoftheifstatement.Incontrast,theconstantsandvariablescreatedwithaguardstatementareavailableinthelinesofcodethatfollowtheguardstatement,asdescribedinEarlyExit.

ImplicitlyUnwrappedOptionals

Page 59: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Asdescribedabove,optionalsindicatethataconstantorvariableisallowedtohave“novalue”.Optionalscanbecheckedwithanifstatementtoseeifavalueexists,andcanbeconditionallyunwrappedwithoptionalbindingtoaccesstheoptional’svalueifitdoesexist.

Sometimesit’sclearfromaprogram’sstructurethatanoptionalwillalwayshaveavalue,afterthatvalueisfirstset.Inthesecases,it’susefultoremovetheneedtocheckandunwraptheoptional’svalueeverytimeit’saccessed,becauseitcanbesafelyassumedtohaveavalueallofthetime.

Thesekindsofoptionalsaredefinedasimplicitlyunwrappedoptionals.Youwriteanimplicitlyunwrappedoptionalbyplacinganexclamationmark(String!)ratherthanaquestionmark(String?)afterthetypethatyouwanttomakeoptional.

Implicitlyunwrappedoptionalsareusefulwhenanoptional’svalueisconfirmedtoexistimmediatelyaftertheoptionalisfirstdefinedandcandefinitelybeassumedtoexistateverypointthereafter.TheprimaryuseofimplicitlyunwrappedoptionalsinSwiftisduringclassinitialization,asdescribedinUnownedReferencesandImplicitlyUnwrappedOptionalProperties.

Animplicitlyunwrappedoptionalisanormaloptionalbehindthescenes,butcanalsobeusedlikeanon-optionalvalue,withouttheneedtounwraptheoptionalvalueeachtimeit’saccessed.ThefollowingexampleshowsthedifferenceinbehaviorbetweenanoptionalstringandanimplicitlyunwrappedoptionalstringwhenaccessingtheirwrappedvalueasanexplicitString:

1 letpossibleString:String?="Anoptionalstring."

2 letforcedString:String=possibleString!//requiresan

exclamationmark

3

4 letassumedString:String!="Animplicitlyunwrappedoptional

string."

5 letimplicitString:String=assumedString//noneedforan

exclamationmark

Page 60: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youcanthinkofanimplicitlyunwrappedoptionalasgivingpermissionfortheoptionaltobeunwrappedautomaticallywheneverit’sused.Ratherthanplacinganexclamationmarkaftertheoptional’snameeachtimeyouuseit,youplaceanexclamationmarkaftertheoptional’stypewhenyoudeclareit.

NOTE

Ifanimplicitlyunwrappedoptionalisnilandyoutrytoaccessitswrappedvalue,you’lltriggeraruntimeerror.Theresultisexactlythesameasifyouplaceanexclamationmarkafteranormaloptionalthatdoesn’tcontainavalue.

Youcanstilltreatanimplicitlyunwrappedoptionallikeanormaloptional,tocheckifitcontainsavalue:

1 ifassumedString!=nil{

2 print(assumedString!)

3 }

4 //Prints"Animplicitlyunwrappedoptionalstring."

Youcanalsouseanimplicitlyunwrappedoptionalwithoptionalbinding,tocheckandunwrapitsvalueinasinglestatement:

1 ifletdefiniteString=assumedString{

2 print(definiteString)

3 }

4 //Prints"Animplicitlyunwrappedoptionalstring."

NOTE

Don’tuseanimplicitlyunwrappedoptionalwhenthere’sapossibilityofavariablebecomingnilatalaterpoint.Alwaysuseanormaloptionaltypeifyouneedtocheckforanilvalueduringthelifetimeofavariable.

ErrorHandling

Page 61: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youuseerrorhandlingtorespondtoerrorconditionsyourprogrammayencounterduringexecution.

Incontrasttooptionals,whichcanusethepresenceorabsenceofavaluetocommunicatesuccessorfailureofafunction,errorhandlingallowsyoutodeterminetheunderlyingcauseoffailure,and,ifnecessary,propagatetheerrortoanotherpartofyourprogram.

Whenafunctionencountersanerrorcondition,itthrowsanerror.Thatfunction’scallercanthencatchtheerrorandrespondappropriately.

1 funccanThrowAnError()throws{

2 //thisfunctionmayormaynotthrowanerror

3 }

Afunctionindicatesthatitcanthrowanerrorbyincludingthethrowskeywordinitsdeclaration.Whenyoucallafunctionthatcanthrowanerror,youprependthetrykeywordtotheexpression.

Swiftautomaticallypropagateserrorsoutoftheircurrentscopeuntilthey’rehandledbyacatchclause.

1 do{

2 trycanThrowAnError()

3 //noerrorwasthrown

4 }catch{

5 //anerrorwasthrown

6 }

Adostatementcreatesanewcontainingscope,whichallowserrorstobepropagatedtooneormorecatchclauses.

Here’sanexampleofhowerrorhandlingcanbeusedtorespondtodifferenterrorconditions:

Page 62: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 funcmakeASandwich()throws{

2 //...

3 }

4

5 do{

6 trymakeASandwich()

7 eatASandwich()

8 }catchSandwichError.outOfCleanDishes{

9 washDishes()

10 }catchSandwichError.missingIngredients(letingredients){

11 buyGroceries(ingredients)

12 }

Inthisexample,themakeASandwich()functionwillthrowanerrorifnocleandishesareavailableorifanyingredientsaremissing.BecausemakeASandwich()canthrowanerror,thefunctioncalliswrappedinatryexpression.Bywrappingthefunctioncallinadostatement,anyerrorsthatarethrownwillbepropagatedtotheprovidedcatchclauses.

Ifnoerroristhrown,theeatASandwich()functioniscalled.IfanerroristhrownanditmatchestheSandwichError.outOfCleanDishescase,thenthewashDishes()functionwillbecalled.IfanerroristhrownanditmatchestheSandwichError.missingIngredientscase,thenthebuyGroceries(_:)functioniscalledwiththeassociated[String]valuecapturedbythecatchpattern.

Throwing,catching,andpropagatingerrorsiscoveredingreaterdetailinErrorHandling.

AssertionsandPreconditions

Assertionsandpreconditionsarechecksthathappenatruntime.Youusethemtomakesureanessentialconditionissatisfiedbeforeexecutinganyfurthercode.If

Page 63: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

theBooleanconditionintheassertionorpreconditionevaluatestotrue,codeexecutioncontinuesasusual.Iftheconditionevaluatestofalse,thecurrentstateoftheprogramisinvalid;codeexecutionends,andyourappisterminated.

Youuseassertionsandpreconditionstoexpresstheassumptionsyoumakeandtheexpectationsyouhavewhilecoding,soyoucanincludethemaspartofyourcode.Assertionshelpyoufindmistakesandincorrectassumptionsduringdevelopment,andpreconditionshelpyoudetectissuesinproduction.

Inadditiontoverifyingyourexpectationsatruntime,assertionsandpreconditionsalsobecomeausefulformofdocumentationwithinthecode.UnliketheerrorconditionsdiscussedinErrorHandlingabove,assertionsandpreconditionsaren’tusedforrecoverableorexpectederrors.Becauseafailedassertionorpreconditionindicatesaninvalidprogramstate,there’snowaytocatchafailedassertion.

Usingassertionsandpreconditionsisn’tasubstitutefordesigningyourcodeinsuchawaythatinvalidconditionsareunlikelytoarise.However,usingthemtoenforcevaliddataandstatecausesyourapptoterminatemorepredictablyifaninvalidstateoccurs,andhelpsmaketheproblemeasiertodebug.Stoppingexecutionassoonasaninvalidstateisdetectedalsohelpslimitthedamagecausedbythatinvalidstate.

Thedifferencebetweenassertionsandpreconditionsisinwhenthey’rechecked:Assertionsarecheckedonlyindebugbuilds,butpreconditionsarecheckedinbothdebugandproductionbuilds.Inproductionbuilds,theconditioninsideanassertionisn’tevaluated.Thismeansyoucanuseasmanyassertionsasyouwantduringyourdevelopmentprocess,withoutimpactingperformanceinproduction.

DebuggingwithAssertionsYouwriteanassertionbycallingtheassert(_:_:file:line:)functionfromtheSwiftstandardlibrary.Youpassthisfunctionanexpressionthatevaluatestotrueorfalseandamessagetodisplayiftheresultoftheconditionisfalse.Forexample:

1 letage=-3

Page 64: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 assert(age>=0,"Aperson'sagecan'tbelessthanzero.")

3 //Thisassertionfailsbecause-3isnot>=0.

Inthisexample,codeexecutioncontinuesifage>=0evaluatestotrue,thatis,ifthevalueofageisnonnegative.Ifthevalueofageisnegative,asinthecodeabove,thenage>=0evaluatestofalse,andtheassertionfails,terminatingtheapplication.

Youcanomittheassertionmessage—forexample,whenitwouldjustrepeattheconditionasprose.

assert(age>=0)

Ifthecodealreadychecksthecondition,youusetheassertionFailure(_:file:line:)functiontoindicatethatanassertionhasfailed.Forexample:

1 ifage>10{

2 print("Youcanridetheroller-coasterortheferris

wheel.")

3 }elseifage>=0{

4 print("Youcanridetheferriswheel.")

5 }else{

6 assertionFailure("Aperson'sagecan'tbelessthanzero.")

7 }

EnforcingPreconditionsUseapreconditionwheneveraconditionhasthepotentialtobefalse,butmustdefinitelybetrueforyourcodetocontinueexecution.Forexample,useapreconditiontocheckthatasubscriptisnotoutofbounds,ortocheckthatafunctionhasbeenpassedavalidvalue.

Youwriteapreconditionbycallingtheprecondition(_:_:file:line:)function.

Page 65: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youpassthisfunctionanexpressionthatevaluatestotrueorfalseandamessagetodisplayiftheresultoftheconditionisfalse.Forexample:

1 //Intheimplementationofasubscript...

2 precondition(index>0,"Indexmustbegreaterthanzero.")

YoucanalsocallthepreconditionFailure(_:file:line:)functiontoindicatethatafailurehasoccurred—forexample,ifthedefaultcaseofaswitchwastaken,butallvalidinputdatashouldhavebeenhandledbyoneoftheswitch’sothercases.

NOTE

Ifyoucompileinuncheckedmode(-Ounchecked),preconditionsaren’tchecked.Thecompilerassumesthatpreconditionsarealwaystrue,anditoptimizesyourcodeaccordingly.However,thefatalError(_:file:line:)functionalwayshaltsexecution,regardlessofoptimizationsettings.

YoucanusethefatalError(_:file:line:)functionduringprototypingandearlydevelopmenttocreatestubsforfunctionalitythathasn’tbeenimplementedyet,bywritingfatalError("Unimplemented")asthestubimplementation.Becausefatalerrorsareneveroptimizedout,unlikeassertionsorpreconditions,youcanbesurethatexecutionalwayshaltsifitencountersastubimplementation.

Page 66: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

BasicOperators

Anoperatorisaspecialsymbolorphrasethatyouusetocheck,change,orcombinevalues.Forexample,theadditionoperator(+)addstwonumbers,asinleti=1+2,andthelogicalANDoperator(&&)combinestwoBooleanvalues,asinifenteredDoorCode&&passedRetinaScan.

SwiftsupportsmoststandardCoperatorsandimprovesseveralcapabilitiestoeliminatecommoncodingerrors.Theassignmentoperator(=)doesn’treturnavalue,topreventitfrombeingmistakenlyusedwhentheequaltooperator(==)isintended.Arithmeticoperators(+,-,*,/,%andsoforth)detectanddisallowvalueoverflow,toavoidunexpectedresultswhenworkingwithnumbersthatbecomelargerorsmallerthantheallowedvaluerangeofthetypethatstoresthem.YoucanoptintovalueoverflowbehaviorbyusingSwift’soverflowoperators,asdescribedinOverflowOperators.

Swiftalsoprovidesrangeoperatorsthataren’tfoundinC,suchasa..<banda...b,asashortcutforexpressingarangeofvalues.

ThischapterdescribesthecommonoperatorsinSwift.AdvancedOperatorscoversSwift’sadvancedoperators,anddescribeshowtodefineyourowncustomoperatorsandimplementthestandardoperatorsforyourowncustomtypes.

Terminology

Operatorsareunary,binary,orternary:

Unaryoperatorsoperateonasingletarget(suchas-a).Unaryprefixoperatorsappearimmediatelybeforetheirtarget(suchas!b),andunarypostfixoperatorsappearimmediatelyaftertheirtarget(suchasc!).

Binaryoperatorsoperateontwotargets(suchas2+3)andareinfixbecausetheyappearinbetweentheirtwotargets.

Page 67: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Ternaryoperatorsoperateonthreetargets.LikeC,Swifthasonlyoneternaryoperator,theternaryconditionaloperator(a?b:c).

Thevaluesthatoperatorsaffectareoperands.Intheexpression1+2,the+symbolisabinaryoperatoranditstwooperandsarethevalues1and2.

AssignmentOperator

Theassignmentoperator(a=b)initializesorupdatesthevalueofawiththevalueofb:

1 letb=10

2 vara=5

3 a=b

4 //aisnowequalto10

Iftherightsideoftheassignmentisatuplewithmultiplevalues,itselementscanbedecomposedintomultipleconstantsorvariablesatonce:

1 let(x,y)=(1,2)

2 //xisequalto1,andyisequalto2

UnliketheassignmentoperatorinCandObjective-C,theassignmentoperatorinSwiftdoesnotitselfreturnavalue.Thefollowingstatementisnotvalid:

1 ifx=y{

2 //Thisisnotvalid,becausex=ydoesnotreturna

value.

3 }

Thisfeaturepreventstheassignmentoperator(=)frombeingusedbyaccidentwhentheequaltooperator(==)isactuallyintended.Bymakingifx=yinvalid,Swifthelpsyoutoavoidthesekindsoferrorsinyourcode.

Page 68: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ArithmeticOperators

Swiftsupportsthefourstandardarithmeticoperatorsforallnumbertypes:

Addition(+)

Subtraction(-)

Multiplication(*)

Division(/)

1 1+2//equals3

2 5-3//equals2

3 2*3//equals6

4 10.0/2.5//equals4.0

UnlikethearithmeticoperatorsinCandObjective-C,theSwiftarithmeticoperatorsdon’tallowvaluestooverflowbydefault.YoucanoptintovalueoverflowbehaviorbyusingSwift’soverflowoperators(suchasa&+b).SeeOverflowOperators.

TheadditionoperatorisalsosupportedforStringconcatenation:

"hello,"+"world"//equals"hello,world"

RemainderOperatorTheremainderoperator(a%b)worksouthowmanymultiplesofbwillfitinsideaandreturnsthevaluethatisleftover(knownastheremainder).

NOTE

Theremainderoperator(%)isalsoknownasamodulooperatorinotherlanguages.However,itsbehaviorinSwiftfornegativenumbersmeansthat,strictlyspeaking,it’saremainderratherthanamodulooperation.

Page 69: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Here’showtheremainderoperatorworks.Tocalculate9%4,youfirstworkouthowmany4swillfitinside9:

Youcanfittwo4sinside9,andtheremainderis1(showninorange).

InSwift,thiswouldbewrittenas:

9%4//equals1

Todeterminetheanswerfora%b,the%operatorcalculatesthefollowingequationandreturnsremainderasitsoutput:

a=(bxsomemultiplier)+remainder

wheresomemultiplieristhelargestnumberofmultiplesofbthatwillfitinsidea.

Inserting9and4intothisequationyields:

9=(4x2)+1

Thesamemethodisappliedwhencalculatingtheremainderforanegativevalueofa:

-9%4//equals-1

Inserting-9and4intotheequationyields:

-9=(4x-2)+-1

givingaremaindervalueof-1.

Thesignofbisignoredfornegativevaluesofb.Thismeansthata%banda%-balwaysgivethesameanswer.

Page 70: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

UnaryMinusOperatorThesignofanumericvaluecanbetoggledusingaprefixed-,knownastheunaryminusoperator:

1 letthree=3

2 letminusThree=-three//minusThreeequals-3

3 letplusThree=-minusThree//plusThreeequals3,or"minus

minusthree"

Theunaryminusoperator(-)isprependeddirectlybeforethevalueitoperateson,withoutanywhitespace.

UnaryPlusOperatorTheunaryplusoperator(+)simplyreturnsthevalueitoperateson,withoutanychange:

1 letminusSix=-6

2 letalsoMinusSix=+minusSix//alsoMinusSixequals-6

Althoughtheunaryplusoperatordoesn’tactuallydoanything,youcanuseittoprovidesymmetryinyourcodeforpositivenumberswhenalsousingtheunaryminusoperatorfornegativenumbers.

CompoundAssignmentOperators

LikeC,Swiftprovidescompoundassignmentoperatorsthatcombineassignment(=)withanotheroperation.Oneexampleistheadditionassignmentoperator(+=):

1 vara=1

2 a+=2

Page 71: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 //aisnowequalto3

Theexpressiona+=2isshorthandfora=a+2.Effectively,theadditionandtheassignmentarecombinedintooneoperatorthatperformsbothtasksatthesametime.

NOTE

Thecompoundassignmentoperatorsdon’treturnavalue.Forexample,youcan’twriteletb=a+=2.

ForinformationabouttheoperatorsprovidedbytheSwiftstandardlibrary,seeOperatorDeclarations.

ComparisonOperators

SwiftsupportsallstandardCcomparisonoperators:

Equalto(a==b)

Notequalto(a!=b)

Greaterthan(a>b)

Lessthan(a<b)

Greaterthanorequalto(a>=b)

Lessthanorequalto(a<=b)

NOTE

Swiftalsoprovidestwoidentityoperators(===and!==),whichyouusetotestwhethertwoobjectreferencesbothrefertothesameobjectinstance.Formoreinformation,seeIdentityOperators.

EachofthecomparisonoperatorsreturnsaBoolvaluetoindicatewhetherornotthestatementistrue:

Page 72: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 1==1//truebecause1isequalto1

2 2!=1//truebecause2isnotequalto1

3 2>1//truebecause2isgreaterthan1

4 1<2//truebecause1islessthan2

5 1>=1//truebecause1isgreaterthanorequalto1

6 2<=1//falsebecause2isnotlessthanorequalto1

Comparisonoperatorsareoftenusedinconditionalstatements,suchastheifstatement:

1 letname="world"

2 ifname=="world"{

3 print("hello,world")

4 }else{

5 print("I'msorry\(name),butIdon'trecognizeyou")

6 }

7 //Prints"hello,world",becausenameisindeedequalto

"world".

Formoreabouttheifstatement,seeControlFlow.

Youcancomparetwotuplesiftheyhavethesametypeandthesamenumberofvalues.Tuplesarecomparedfromlefttoright,onevalueatatime,untilthecomparisonfindstwovaluesthataren’tequal.Thosetwovaluesarecompared,andtheresultofthatcomparisondeterminestheoverallresultofthetuplecomparison.Ifalltheelementsareequal,thenthetuplesthemselvesareequal.Forexample:

1 (1,"zebra")<(2,"apple")//truebecause1islessthan2;

"zebra"and"apple"arenotcompared

2 (3,"apple")<(3,"bird")//truebecause3isequalto3,

and"apple"islessthan"bird"

Page 73: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 (4,"dog")==(4,"dog")//truebecause4isequalto4,

and"dog"isequalto"dog"

Intheexampleabove,youcanseetheleft-to-rightcomparisonbehavioronthefirstline.Because1islessthan2,(1,"zebra")isconsideredlessthan(2,"apple"),regardlessofanyothervaluesinthetuples.Itdoesn’tmatterthat"zebra"isn’tlessthan"apple",becausethecomparisonisalreadydeterminedbythetuples’firstelements.However,whenthetuples’firstelementsarethesame,theirsecondelementsarecompared—thisiswhathappensonthesecondandthirdline.

Tuplescanbecomparedwithagivenoperatoronlyiftheoperatorcanbeappliedtoeachvalueintherespectivetuples.Forexample,asdemonstratedinthecodebelow,youcancomparetwotuplesoftype(String,Int)becausebothStringandIntvaluescanbecomparedusingthe<operator.Incontrast,twotuplesoftype(String,Bool)can’tbecomparedwiththe<operatorbecausethe<operatorcan’tbeappliedtoBoolvalues.

1 ("blue",-1)<("purple",1)//OK,evaluatestotrue

2 ("blue",false)<("purple",true)//Errorbecause<can't

compareBooleanvalues

NOTE

TheSwiftstandardlibraryincludestuplecomparisonoperatorsfortupleswithfewerthansevenelements.Tocomparetupleswithsevenormoreelements,youmustimplementthecomparisonoperatorsyourself.

TernaryConditionalOperator

Theternaryconditionaloperatorisaspecialoperatorwiththreeparts,whichtakestheformquestion?answer1:answer2.It’sashortcutforevaluatingoneoftwoexpressionsbasedonwhetherquestionistrueorfalse.Ifquestionistrue,itevaluatesanswer1andreturnsitsvalue;otherwise,itevaluatesanswer2

Page 74: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

andreturnsitsvalue.

Theternaryconditionaloperatorisshorthandforthecodebelow:

1 ifquestion{

2 answer1

3 }else{

4 answer2

5 }

Here’sanexample,whichcalculatestheheightforatablerow.Therowheightshouldbe50pointstallerthanthecontentheightiftherowhasaheader,and20pointstalleriftherowdoesn’thaveaheader:

1 letcontentHeight=40

2 lethasHeader=true

3 letrowHeight=contentHeight+(hasHeader?50:20)

4 //rowHeightisequalto90

Theexampleaboveisshorthandforthecodebelow:

1 letcontentHeight=40

2 lethasHeader=true

3 letrowHeight:Int

4 ifhasHeader{

5 rowHeight=contentHeight+50

6 }else{

7 rowHeight=contentHeight+20

8 }

9 //rowHeightisequalto90

Thefirstexample’suseoftheternaryconditionaloperatormeansthatrowHeightcanbesettothecorrectvalueonasinglelineofcode,whichismoreconcise

Page 75: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thanthecodeusedinthesecondexample.

Theternaryconditionaloperatorprovidesanefficientshorthandfordecidingwhichoftwoexpressionstoconsider.Usetheternaryconditionaloperatorwithcare,however.Itsconcisenesscanleadtohard-to-readcodeifoverused.Avoidcombiningmultipleinstancesoftheternaryconditionaloperatorintoonecompoundstatement.

Nil-CoalescingOperator

Thenil-coalescingoperator(a??b)unwrapsanoptionalaifitcontainsavalue,orreturnsadefaultvaluebifaisnil.Theexpressionaisalwaysofanoptionaltype.Theexpressionbmustmatchthetypethatisstoredinsidea.

Thenil-coalescingoperatorisshorthandforthecodebelow:

a!=nil?a!:b

Thecodeaboveusestheternaryconditionaloperatorandforcedunwrapping(a!)toaccessthevaluewrappedinsideawhenaisnotnil,andtoreturnbotherwise.Thenil-coalescingoperatorprovidesamoreelegantwaytoencapsulatethisconditionalcheckingandunwrappinginaconciseandreadableform.

NOTE

Ifthevalueofaisnon-nil,thevalueofbisnotevaluated.Thisisknownasshort-circuitevaluation.

Theexamplebelowusesthenil-coalescingoperatortochoosebetweenadefaultcolornameandanoptionaluser-definedcolorname:

1 letdefaultColorName="red"

2 varuserDefinedColorName:String?//defaultstonil

3

Page 76: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 varcolorNameToUse=userDefinedColorName??defaultColorName

5 //userDefinedColorNameisnil,socolorNameToUseissettothe

defaultof"red"

TheuserDefinedColorNamevariableisdefinedasanoptionalString,withadefaultvalueofnil.BecauseuserDefinedColorNameisofanoptionaltype,youcanusethenil-coalescingoperatortoconsideritsvalue.Intheexampleabove,theoperatorisusedtodetermineaninitialvalueforaStringvariablecalledcolorNameToUse.BecauseuserDefinedColorNameisnil,theexpressionuserDefinedColorName??defaultColorNamereturnsthevalueofdefaultColorName,or"red".

Ifyouassignanon-nilvaluetouserDefinedColorNameandperformthenil-coalescingoperatorcheckagain,thevaluewrappedinsideuserDefinedColorNameisusedinsteadofthedefault:

1 userDefinedColorName="green"

2 colorNameToUse=userDefinedColorName??defaultColorName

3 //userDefinedColorNameisnotnil,socolorNameToUseissetto

"green"

RangeOperators

Swiftincludesseveralrangeoperators,whichareshortcutsforexpressingarangeofvalues.

ClosedRangeOperatorTheclosedrangeoperator(a...b)definesarangethatrunsfromatob,andincludesthevaluesaandb.Thevalueofamustnotbegreaterthanb.

Theclosedrangeoperatorisusefulwheniteratingoverarangeinwhichyou

Page 77: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

wantallofthevaluestobeused,suchaswithafor-inloop:

1 forindexin1...5{

2 print("\(index)times5is\(index*5)")

3 }

4 //1times5is5

5 //2times5is10

6 //3times5is15

7 //4times5is20

8 //5times5is25

Formoreaboutfor-inloops,seeControlFlow.

Half-OpenRangeOperatorThehalf-openrangeoperator(a..<b)definesarangethatrunsfromatob,butdoesn’tincludeb.It’ssaidtobehalf-openbecauseitcontainsitsfirstvalue,butnotitsfinalvalue.Aswiththeclosedrangeoperator,thevalueofamustnotbegreaterthanb.Ifthevalueofaisequaltob,thentheresultingrangewillbeempty.

Half-openrangesareparticularlyusefulwhenyouworkwithzero-basedlistssuchasarrays,whereit’susefultocountupto(butnotincluding)thelengthofthelist:

1 letnames=["Anna","Alex","Brian","Jack"]

2 letcount=names.count

3 foriin0..<count{

4 print("Person\(i+1)iscalled\(names[i])")

5 }

6 //Person1iscalledAnna

7 //Person2iscalledAlex

Page 78: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 //Person3iscalledBrian

9 //Person4iscalledJack

Notethatthearraycontainsfouritems,but0..<countonlycountsasfaras3(theindexofthelastiteminthearray),becauseit’sahalf-openrange.Formoreaboutarrays,seeArrays.

One-SidedRangesTheclosedrangeoperatorhasanalternativeformforrangesthatcontinueasfaraspossibleinonedirection—forexample,arangethatincludesalltheelementsofanarrayfromindex2totheendofthearray.Inthesecases,youcanomitthevaluefromonesideoftherangeoperator.Thiskindofrangeiscalledaone-sidedrangebecausetheoperatorhasavalueononlyoneside.Forexample:

1 fornameinnames[2...]{

2 print(name)

3 }

4 //Brian

5 //Jack

6

7 fornameinnames[...2]{

8 print(name)

9 }

10 //Anna

11 //Alex

12 //Brian

Thehalf-openrangeoperatoralsohasaone-sidedformthat’swrittenwithonlyitsfinalvalue.Justlikewhenyouincludeavalueonbothsides,thefinalvalueisn’tpartoftherange.Forexample:

Page 79: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 fornameinnames[..<2]{

2 print(name)

3 }

4 //Anna

5 //Alex

One-sidedrangescanbeusedinothercontexts,notjustinsubscripts.Youcan’titerateoveraone-sidedrangethatomitsafirstvalue,becauseitisn’tclearwhereiterationshouldbegin.Youcaniterateoveraone-sidedrangethatomitsitsfinalvalue;however,becausetherangecontinuesindefinitely,makesureyouaddanexplicitendconditionfortheloop.Youcanalsocheckwhetheraone-sidedrangecontainsaparticularvalue,asshowninthecodebelow.

1 letrange=...5

2 range.contains(7)//false

3 range.contains(4)//true

4 range.contains(-1)//true

LogicalOperators

LogicaloperatorsmodifyorcombinetheBooleanlogicvaluestrueandfalse.SwiftsupportsthethreestandardlogicaloperatorsfoundinC-basedlanguages:

LogicalNOT(!a)

LogicalAND(a&&b)

LogicalOR(a||b)

LogicalNOTOperatorThelogicalNOToperator(!a)invertsaBooleanvaluesothattruebecomes

Page 80: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

false,andfalsebecomestrue.

ThelogicalNOToperatorisaprefixoperator,andappearsimmediatelybeforethevalueitoperateson,withoutanywhitespace.Itcanbereadas“nota”,asseeninthefollowingexample:

1 letallowedEntry=false

2 if!allowedEntry{

3 print("ACCESSDENIED")

4 }

5 //Prints"ACCESSDENIED"

Thephraseif!allowedEntrycanbereadas“ifnotallowedentry.”Thesubsequentlineisonlyexecutedif“notallowedentry”istrue;thatis,ifallowedEntryisfalse.

Asinthisexample,carefulchoiceofBooleanconstantandvariablenamescanhelptokeepcodereadableandconcise,whileavoidingdoublenegativesorconfusinglogicstatements.

LogicalANDOperatorThelogicalANDoperator(a&&b)createslogicalexpressionswherebothvaluesmustbetruefortheoverallexpressiontoalsobetrue.

Ifeithervalueisfalse,theoverallexpressionwillalsobefalse.Infact,ifthefirstvalueisfalse,thesecondvaluewon’tevenbeevaluated,becauseitcan’tpossiblymaketheoverallexpressionequatetotrue.Thisisknownasshort-circuitevaluation.

ThisexampleconsiderstwoBoolvaluesandonlyallowsaccessifbothvaluesaretrue:

1 letenteredDoorCode=true

2 letpassedRetinaScan=false

Page 81: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 ifenteredDoorCode&&passedRetinaScan{

4 print("Welcome!")

5 }else{

6 print("ACCESSDENIED")

7 }

8 //Prints"ACCESSDENIED"

LogicalOROperatorThelogicalORoperator(a||b)isaninfixoperatormadefromtwoadjacentpipecharacters.Youuseittocreatelogicalexpressionsinwhichonlyoneofthetwovalueshastobetruefortheoverallexpressiontobetrue.

LiketheLogicalANDoperatorabove,theLogicalORoperatorusesshort-circuitevaluationtoconsideritsexpressions.IftheleftsideofaLogicalORexpressionistrue,therightsideisnotevaluated,becauseitcan’tchangetheoutcomeoftheoverallexpression.

Intheexamplebelow,thefirstBoolvalue(hasDoorKey)isfalse,butthesecondvalue(knowsOverridePassword)istrue.Becauseonevalueistrue,theoverallexpressionalsoevaluatestotrue,andaccessisallowed:

1 lethasDoorKey=false

2 letknowsOverridePassword=true

3 ifhasDoorKey||knowsOverridePassword{

4 print("Welcome!")

5 }else{

6 print("ACCESSDENIED")

7 }

8 //Prints"Welcome!"

Page 82: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

CombiningLogicalOperatorsYoucancombinemultiplelogicaloperatorstocreatelongercompoundexpressions:

1 ifenteredDoorCode&&passedRetinaScan||hasDoorKey||

knowsOverridePassword{

2 print("Welcome!")

3 }else{

4 print("ACCESSDENIED")

5 }

6 //Prints"Welcome!"

Thisexampleusesmultiple&&and||operatorstocreatealongercompoundexpression.However,the&&and||operatorsstilloperateononlytwovalues,sothisisactuallythreesmallerexpressionschainedtogether.Theexamplecanbereadas:

Ifwe’veenteredthecorrectdoorcodeandpassedtheretinascan,orifwehaveavaliddoorkey,orifweknowtheemergencyoverridepassword,thenallowaccess.

BasedonthevaluesofenteredDoorCode,passedRetinaScan,andhasDoorKey,thefirsttwosubexpressionsarefalse.However,theemergencyoverridepasswordisknown,sotheoverallcompoundexpressionstillevaluatestotrue.

NOTE

TheSwiftlogicaloperators&&and||areleft-associative,meaningthatcompoundexpressionswithmultiplelogicaloperatorsevaluatetheleftmostsubexpressionfirst.

ExplicitParenthesesIt’ssometimesusefultoincludeparentheseswhenthey’renotstrictlyneeded,tomaketheintentionofacomplexexpressioneasiertoread.Inthedooraccessexampleabove,it’susefultoaddparenthesesaroundthefirstpartofthe

Page 83: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

compoundexpressiontomakeitsintentexplicit:

1 if(enteredDoorCode&&passedRetinaScan)||hasDoorKey||

knowsOverridePassword{

2 print("Welcome!")

3 }else{

4 print("ACCESSDENIED")

5 }

6 //Prints"Welcome!"

Theparenthesesmakeitclearthatthefirsttwovaluesareconsideredaspartofaseparatepossiblestateintheoveralllogic.Theoutputofthecompoundexpressiondoesn’tchange,buttheoverallintentionisclearertothereader.Readabilityisalwayspreferredoverbrevity;useparentheseswheretheyhelptomakeyourintentionsclear.

Page 84: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

StringsandCharacters

Astringisaseriesofcharacters,suchas"hello,world"or"albatross".SwiftstringsarerepresentedbytheStringtype.ThecontentsofaStringcanbeaccessedinvariousways,includingasacollectionofCharactervalues.

Swift’sStringandCharactertypesprovideafast,Unicode-compliantwaytoworkwithtextinyourcode.Thesyntaxforstringcreationandmanipulationislightweightandreadable,withastringliteralsyntaxthatissimilartoC.Stringconcatenationisassimpleascombiningtwostringswiththe+operator,andstringmutabilityismanagedbychoosingbetweenaconstantoravariable,justlikeanyothervalueinSwift.Youcanalsousestringstoinsertconstants,variables,literals,andexpressionsintolongerstrings,inaprocessknownasstringinterpolation.Thismakesiteasytocreatecustomstringvaluesfordisplay,storage,andprinting.

Despitethissimplicityofsyntax,Swift’sStringtypeisafast,modernstringimplementation.Everystringiscomposedofencoding-independentUnicodecharacters,andprovidessupportforaccessingthosecharactersinvariousUnicoderepresentations.

NOTE

Swift’sStringtypeisbridgedwithFoundation’sNSStringclass.FoundationalsoextendsStringtoexposemethodsdefinedbyNSString.Thismeans,ifyouimportFoundation,youcanaccessthoseNSStringmethodsonStringwithoutcasting.

FormoreinformationaboutusingStringwithFoundationandCocoa,seeBridgingBetweenStringandNSString.

StringLiterals

YoucanincludepredefinedStringvalueswithinyourcodeasstringliterals.Astringliteralisasequenceofcharacterssurroundedbydoublequotationmarks(").

Page 85: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Useastringliteralasaninitialvalueforaconstantorvariable:

letsomeString="Somestringliteralvalue"

NotethatSwiftinfersatypeofStringforthesomeStringconstantbecauseit’sinitializedwithastringliteralvalue.

MultilineStringLiteralsIfyouneedastringthatspansseverallines,useamultilinestringliteral—asequenceofcharacterssurroundedbythreedoublequotationmarks:

1 letquotation="""

2 TheWhiteRabbitputonhisspectacles."WhereshallIbegin,

3 pleaseyourMajesty?"heasked.

4

5 "Beginatthebeginning,"theKingsaidgravely,"andgoon

6 tillyoucometotheend;thenstop."

7 """

Amultilinestringliteralincludesallofthelinesbetweenitsopeningandclosingquotationmarks.Thestringbeginsonthefirstlineaftertheopeningquotationmarks(""")andendsonthelinebeforetheclosingquotationmarks,whichmeansthatneitherofthestringsbelowstartorendwithalinebreak:

1 letsingleLineString="Thesearethesame."

2 letmultilineString="""

3 Thesearethesame.

4 """

Whenyoursourcecodeincludesalinebreakinsideofamultilinestringliteral,thatlinebreakalsoappearsinthestring’svalue.Ifyouwanttouselinebreakstomakeyoursourcecodeeasiertoread,butyoudon’twantthelinebreakstobe

Page 86: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

partofthestring’svalue,writeabackslash(\)attheendofthoselines:

1 letsoftWrappedQuotation="""

2 TheWhiteRabbitputonhisspectacles."WhereshallIbegin,

\

3 pleaseyourMajesty?"heasked.

4

5 "Beginatthebeginning,"theKingsaidgravely,"andgoon\

6 tillyoucometotheend;thenstop."

7 """

Tomakeamultilinestringliteralthatbeginsorendswithalinefeed,writeablanklineasthefirstorlastline.Forexample:

1 letlineBreaks="""

2

3 Thisstringstartswithalinebreak.

4 Italsoendswithalinebreak.

5

6 """

Amultilinestringcanbeindentedtomatchthesurroundingcode.Thewhitespacebeforetheclosingquotationmarks(""")tellsSwiftwhatwhitespacetoignorebeforealloftheotherlines.However,ifyouwritewhitespaceatthebeginningofalineinadditiontowhat’sbeforetheclosingquotationmarks,thatwhitespaceisincluded.

Intheexampleabove,eventhoughtheentiremultilinestringliteralisindented,

Page 87: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thefirstandlastlinesinthestringdon’tbeginwithanywhitespace.Themiddlelinehasmoreindentationthantheclosingquotationmarks,soitstartswiththatextrafour-spaceindentation.

SpecialCharactersinStringLiteralsStringliteralscanincludethefollowingspecialcharacters:

Theescapedspecialcharacters\0(nullcharacter),\\(backslash),\t(horizontaltab),\n(linefeed),\r(carriagereturn),\"(doublequotationmark)and\'(singlequotationmark)

AnarbitraryUnicodescalarvalue,writtenas\u{n},wherenisa1–8digithexadecimalnumber(UnicodeisdiscussedinUnicodebelow)

Thecodebelowshowsfourexamplesofthesespecialcharacters.ThewiseWordsconstantcontainstwoescapeddoublequotationmarks.ThedollarSign,blackHeart,andsparklingHeartconstantsdemonstratetheUnicodescalarformat:

1 letwiseWords="\"Imaginationismoreimportantthan

knowledge\"-Einstein"

2 //"Imaginationismoreimportantthanknowledge"-Einstein

3 letdollarSign="\u{24}"//$,UnicodescalarU+0024

4 letblackHeart="\u{2665}"//♥,UnicodescalarU+2665

5 letsparklingHeart="\u{1F496}"//,UnicodescalarU+1F496

Becausemultilinestringliteralsusethreedoublequotationmarksinsteadofjustone,youcanincludeadoublequotationmark(")insideofamultilinestringliteralwithoutescapingit.Toincludethetext"""inamultilinestring,escapeatleastoneofthequotationmarks.Forexample:

1 letthreeDoubleQuotationMarks="""

2 Escapingthefirstquotationmark\"""

Page 88: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 Escapingallthreequotationmarks\"\"\"

4 """

ExtendedStringDelimitersYoucanplaceastringliteralwithinextendeddelimiterstoincludespecialcharactersinastringwithoutinvokingtheireffect.Youplaceyourstringwithinquotationmarks(")andsurroundthatwithnumbersigns(#).Forexample,printingthestringliteral#"Line1\nLine2"#printsthelinefeedescapesequence(\n)ratherthanprintingthestringacrosstwolines.

Ifyouneedthespecialeffectsofacharacterinastringliteral,matchthenumberofnumbersignswithinthestringfollowingtheescapecharacter(\).Forexample,ifyourstringis#"Line1\nLine2"#andyouwanttobreaktheline,youcanuse#"Line1\#nLine2"#instead.Similarly,###"Line1\###nLine2"###alsobreakstheline.

Stringliteralscreatedusingextendeddelimiterscanalsobemultilinestringliterals.Youcanuseextendeddelimiterstoincludethetext"""inamultilinestring,overridingthedefaultbehaviorthatendstheliteral.Forexample:

1 letthreeMoreDoubleQuotationMarks=#"""

2 Herearethreemoredoublequotes:"""

3 """#

InitializinganEmptyString

TocreateanemptyStringvalueasthestartingpointforbuildingalongerstring,eitherassignanemptystringliteraltoavariable,orinitializeanewStringinstancewithinitializersyntax:

1 varemptyString=""//emptystringliteral

Page 89: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 varanotherEmptyString=String()//initializersyntax

3 //thesetwostringsarebothempty,andareequivalenttoeach

other

FindoutwhetheraStringvalueisemptybycheckingitsBooleanisEmptyproperty:

1 ifemptyString.isEmpty{

2 print("Nothingtoseehere")

3 }

4 //Prints"Nothingtoseehere"

StringMutability

YouindicatewhetheraparticularStringcanbemodified(ormutated)byassigningittoavariable(inwhichcaseitcanbemodified),ortoaconstant(inwhichcaseitcan’tbemodified):

1 varvariableString="Horse"

2 variableString+="andcarriage"

3 //variableStringisnow"Horseandcarriage"

4

5 letconstantString="Highlander"

6 constantString+="andanotherHighlander"

7 //thisreportsacompile-timeerror-aconstantstringcannot

bemodified

NOTE

ThisapproachisdifferentfromstringmutationinObjective-CandCocoa,whereyouchoosebetweentwoclasses(NSStringandNSMutableString)toindicatewhetherastringcanbemutated.

Page 90: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

StringsAreValueTypes

Swift’sStringtypeisavaluetype.IfyoucreateanewStringvalue,thatStringvalueiscopiedwhenit’spassedtoafunctionormethod,orwhenit’sassignedtoaconstantorvariable.Ineachcase,anewcopyoftheexistingStringvalueiscreated,andthenewcopyispassedorassigned,nottheoriginalversion.ValuetypesaredescribedinStructuresandEnumerationsAreValueTypes.

Swift’scopy-by-defaultStringbehaviorensuresthatwhenafunctionormethodpassesyouaStringvalue,it’sclearthatyouownthatexactStringvalue,regardlessofwhereitcamefrom.Youcanbeconfidentthatthestringyouarepassedwon’tbemodifiedunlessyoumodifyityourself.

Behindthescenes,Swift’scompileroptimizesstringusagesothatactualcopyingtakesplaceonlywhenabsolutelynecessary.Thismeansyoualwaysgetgreatperformancewhenworkingwithstringsasvaluetypes.

WorkingwithCharacters

YoucanaccesstheindividualCharactervaluesforaStringbyiteratingoverthestringwithafor-inloop:

1 forcharacterin"Dog!" {

2 print(character)

3 }

4 //D

5 //o

6 //g

7 //!

8 //

Thefor-inloopisdescribedinFor-InLoops.

Page 91: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Alternatively,youcancreateastand-aloneCharacterconstantorvariablefromasingle-characterstringliteralbyprovidingaCharactertypeannotation:

letexclamationMark:Character="!"

StringvaluescanbeconstructedbypassinganarrayofCharactervaluesasanargumenttoitsinitializer:

1 letcatCharacters:[Character]=["C","a","t","!"," "]

2 letcatString=String(catCharacters)

3 print(catString)

4 //Prints"Cat! "

ConcatenatingStringsandCharacters

Stringvaluescanbeaddedtogether(orconcatenated)withtheadditionoperator(+)tocreateanewStringvalue:

1 letstring1="hello"

2 letstring2="there"

3 varwelcome=string1+string2

4 //welcomenowequals"hellothere"

YoucanalsoappendaStringvaluetoanexistingStringvariablewiththeadditionassignmentoperator(+=):

1 varinstruction="lookover"

2 instruction+=string2

3 //instructionnowequals"lookoverthere"

YoucanappendaCharactervaluetoaStringvariablewiththeStringtype’sappend()method:

Page 92: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letexclamationMark:Character="!"

2 welcome.append(exclamationMark)

3 //welcomenowequals"hellothere!"

NOTE

Youcan’tappendaStringorCharactertoanexistingCharactervariable,becauseaCharactervaluemustcontainasinglecharacteronly.

Ifyou’reusingmultilinestringliteralstobuildupthelinesofalongerstring,youwanteverylineinthestringtoendwithalinebreak,includingthelastline.Forexample:

1 letbadStart="""

2 one

3 two

4 """

5 letend="""

6 three

7 """

8 print(badStart+end)

9 //Printstwolines:

10 //one

11 //twothree

12

13 letgoodStart="""

14 one

15 two

16

17 """

18 print(goodStart+end)

19 //Printsthreelines:

Page 93: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

20 //one

21 //two

22 //three

Inthecodeabove,concatenatingbadStartwithendproducesatwo-linestring,whichisn’tthedesiredresult.BecausethelastlineofbadStartdoesn’tendwithalinebreak,thatlinegetscombinedwiththefirstlineofend.Incontrast,bothlinesofgoodStartendwithalinebreak,sowhenit’scombinedwithendtheresulthasthreelines,asexpected.

StringInterpolation

StringinterpolationisawaytoconstructanewStringvaluefromamixofconstants,variables,literals,andexpressionsbyincludingtheirvaluesinsideastringliteral.Youcanusestringinterpolationinbothsingle-lineandmultilinestringliterals.Eachitemthatyouinsertintothestringliteraliswrappedinapairofparentheses,prefixedbyabackslash(\):

1 letmultiplier=3

2 letmessage="\(multiplier)times2.5is\(Double(multiplier)

*2.5)"

3 //messageis"3times2.5is7.5"

Intheexampleabove,thevalueofmultiplierisinsertedintoastringliteralas\(multiplier).Thisplaceholderisreplacedwiththeactualvalueofmultiplierwhenthestringinterpolationisevaluatedtocreateanactualstring.

Thevalueofmultiplierisalsopartofalargerexpressionlaterinthestring.ThisexpressioncalculatesthevalueofDouble(multiplier)*2.5andinsertstheresult(7.5)intothestring.Inthiscase,theexpressioniswrittenas\(Double(multiplier)*2.5)whenit’sincludedinsidethestringliteral.

Youcanuseextendedstringdelimiterstocreatestringscontainingcharacters

Page 94: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thatwouldotherwisebetreatedasastringinterpolation.Forexample:

1 print(#"WriteaninterpolatedstringinSwiftusing\

(multiplier)."#)

2 //Prints"WriteaninterpolatedstringinSwiftusing\

(multiplier)."

Tousestringinterpolationinsideastringthatusesextendeddelimiters,matchthenumberofnumbersignsbeforethebackslashtothenumberofnumbersignsatthebeginningandendofthestring.Forexample:

1 print(#"6times7is\#(6*7)."#)

2 //Prints"6times7is42."

NOTE

Theexpressionsyouwriteinsideparentheseswithinaninterpolatedstringcan’tcontainanunescapedbackslash(\),acarriagereturn,oralinefeed.However,theycancontainotherstringliterals.

Unicode

Unicodeisaninternationalstandardforencoding,representing,andprocessingtextindifferentwritingsystems.Itenablesyoutorepresentalmostanycharacterfromanylanguageinastandardizedform,andtoreadandwritethosecharacterstoandfromanexternalsourcesuchasatextfileorwebpage.Swift’sStringandCharactertypesarefullyUnicode-compliant,asdescribedinthissection.

UnicodeScalarValuesBehindthescenes,Swift’snativeStringtypeisbuiltfromUnicodescalarvalues.AUnicodescalarvalueisaunique21-bitnumberforacharacterormodifier,suchasU+0061forLATINSMALLLETTERA("a"),orU+1F425forFRONT-FACINGBABYCHICK("" ).

Page 95: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Notethatnotall21-bitUnicodescalarvaluesareassignedtoacharacter—somescalarsarereservedforfutureassignmentorforuseinUTF-16encoding.Scalarvaluesthathavebeenassignedtoacharactertypicallyalsohaveaname,suchasLATINSMALLLETTERAandFRONT-FACINGBABYCHICKintheexamplesabove.

ExtendedGraphemeClustersEveryinstanceofSwift’sCharactertyperepresentsasingleextendedgraphemecluster.AnextendedgraphemeclusterisasequenceofoneormoreUnicodescalarsthat(whencombined)produceasinglehuman-readablecharacter.

Here’sanexample.TheletterécanberepresentedasthesingleUnicodescalaré(LATINSMALLLETTEREWITHACUTE,orU+00E9).However,thesamelettercanalsoberepresentedasapairofscalars—astandardlettere(LATINSMALLLETTERE,orU+0065),followedbytheCOMBININGACUTEACCENTscalar(U+0301).TheCOMBININGACUTEACCENTscalarisgraphicallyappliedtothescalarthatprecedesit,turninganeintoanéwhenit’srenderedbyaUnicode-awaretext-renderingsystem.

Inbothcases,theletteréisrepresentedasasingleSwiftCharactervaluethatrepresentsanextendedgraphemecluster.Inthefirstcase,theclustercontainsasinglescalar;inthesecondcase,it’saclusteroftwoscalars:

1 leteAcute:Character="\u{E9}"//é

2 letcombinedEAcute:Character="\u{65}\u{301}"//e

followedby

3 //eAcuteisé,combinedEAcuteisé

ExtendedgraphemeclustersareaflexiblewaytorepresentmanycomplexscriptcharactersasasingleCharactervalue.Forexample,HangulsyllablesfromtheKoreanalphabetcanberepresentedaseitheraprecomposedordecomposedsequence.BothoftheserepresentationsqualifyasasingleCharactervalueinSwift:

1 letprecomposed:Character="\u{D55C}"//

Page 96: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 letdecomposed:Character="\u{1112}\u{1161}\u{11AB}"//�,

�,�

3 //precomposedis�,decomposedis�

Extendedgraphemeclustersenablescalarsforenclosingmarks(suchasCOMBININGENCLOSINGCIRCLE,orU+20DD)toencloseotherUnicodescalarsaspartofasingleCharactervalue:

1 letenclosedEAcute:Character="\u{E9}\u{20DD}"

2 //enclosedEAcuteisé�

UnicodescalarsforregionalindicatorsymbolscanbecombinedinpairstomakeasingleCharactervalue,suchasthiscombinationofREGIONALINDICATORSYMBOLLETTERU(U+1F1FA)andREGIONALINDICATORSYMBOLLETTERS(U+1F1F8):

1 letregionalIndicatorForUS:Character="\u{1F1FA}\u{1F1F8}"

2 //regionalIndicatorForUSis��

CountingCharacters

ToretrieveacountoftheCharactervaluesinastring,usethecountpropertyofthestring:

1 letunusualMenagerie="Koala,Snail,Penguin,Dromedary

"

2 print("unusualMenageriehas\(unusualMenagerie.count)

characters")

3 //Prints"unusualMenageriehas40characters"

NotethatSwift’suseofextendedgraphemeclustersforCharactervaluesmeansthatstringconcatenationandmodificationmaynotalwaysaffectastring’scharactercount.

Page 97: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Forexample,ifyouinitializeanewstringwiththefour-characterwordcafe,andthenappendaCOMBININGACUTEACCENT(U+0301)totheendofthestring,theresultingstringwillstillhaveacharactercountof4,withafourthcharacterofé,note:

1 varword="cafe"

2 print("thenumberofcharactersin\(word)is\(word.count)")

3 //Prints"thenumberofcharactersincafeis4"

4

5 word+="\u{301}"//COMBININGACUTEACCENT,U+0301

6

7 print("thenumberofcharactersin\(word)is\(word.count)")

8 //Prints"thenumberofcharactersincaféis4"

NOTE

ExtendedgraphemeclusterscanbecomposedofmultipleUnicodescalars.Thismeansthatdifferentcharacters—anddifferentrepresentationsofthesamecharacter—canrequiredifferentamountsofmemorytostore.Becauseofthis,charactersinSwiftdon’teachtakeupthesameamountofmemorywithinastring’srepresentation.Asaresult,thenumberofcharactersinastringcan’tbecalculatedwithoutiteratingthroughthestringtodetermineitsextendedgraphemeclusterboundaries.Ifyouareworkingwithparticularlylongstringvalues,beawarethatthecountpropertymustiterateovertheUnicodescalarsintheentirestringinordertodeterminethecharactersforthatstring.

Thecountofthecharactersreturnedbythecountpropertyisn’talwaysthesameasthelengthpropertyofanNSStringthatcontainsthesamecharacters.ThelengthofanNSStringisbasedonthenumberof16-bitcodeunitswithinthestring’sUTF-16representationandnotthenumberofUnicodeextendedgraphemeclusterswithinthestring.

AccessingandModifyingaString

Youaccessandmodifyastringthroughitsmethodsandproperties,orbyusingsubscriptsyntax.

Page 98: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

StringIndicesEachStringvaluehasanassociatedindextype,String.Index,whichcorrespondstothepositionofeachCharacterinthestring.

Asmentionedabove,differentcharacterscanrequiredifferentamountsofmemorytostore,soinordertodeterminewhichCharacterisataparticularposition,youmustiterateovereachUnicodescalarfromthestartorendofthatString.Forthisreason,Swiftstringscan’tbeindexedbyintegervalues.

UsethestartIndexpropertytoaccessthepositionofthefirstCharacterofaString.TheendIndexpropertyisthepositionafterthelastcharacterinaString.Asaresult,theendIndexpropertyisn’tavalidargumenttoastring’ssubscript.IfaStringisempty,startIndexandendIndexareequal.

Youaccesstheindicesbeforeandafteragivenindexusingtheindex(before:)andindex(after:)methodsofString.Toaccessanindexfartherawayfromthegivenindex,youcanusetheindex(_:offsetBy:)methodinsteadofcallingoneofthesemethodsmultipletimes.

YoucanusesubscriptsyntaxtoaccesstheCharacterataparticularStringindex.

1 letgreeting="GutenTag!"

2 greeting[greeting.startIndex]

3 //G

4 greeting[greeting.index(before:greeting.endIndex)]

5 //!

6 greeting[greeting.index(after:greeting.startIndex)]

7 //u

8 letindex=greeting.index(greeting.startIndex,offsetBy:7)

9 greeting[index]

10 //a

Attemptingtoaccessanindexoutsideofastring’srangeoraCharacteratanindexoutsideofastring’srangewilltriggeraruntimeerror.

Page 99: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 greeting[greeting.endIndex]//Error

2 greeting.index(after:greeting.endIndex)//Error

Usetheindicespropertytoaccessalloftheindicesofindividualcharactersinastring.

1 forindexingreeting.indices{

2 print("\(greeting[index])",terminator:"")

3 }

4 //Prints"GutenTag!"

NOTE

YoucanusethestartIndexandendIndexpropertiesandtheindex(before:),index(after:),andindex(_:offsetBy:)methodsonanytypethatconformstotheCollectionprotocol.ThisincludesString,asshownhere,aswellascollectiontypessuchasArray,Dictionary,andSet.

InsertingandRemovingToinsertasinglecharacterintoastringataspecifiedindex,usetheinsert(_:at:)method,andtoinsertthecontentsofanotherstringataspecifiedindex,usetheinsert(contentsOf:at:)method.

1 varwelcome="hello"

2 welcome.insert("!",at:welcome.endIndex)

3 //welcomenowequals"hello!"

4

5 welcome.insert(contentsOf:"there",at:welcome.index(before:

welcome.endIndex))

6 //welcomenowequals"hellothere!"

Toremoveasinglecharacterfromastringataspecifiedindex,usetheremove(at:)method,andtoremoveasubstringataspecifiedrange,usethe

Page 100: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

removeSubrange(_:)method:

1 welcome.remove(at:welcome.index(before:welcome.endIndex))

2 //welcomenowequals"hellothere"

3

4 letrange=welcome.index(welcome.endIndex,offsetBy:-6)..

<welcome.endIndex

5 welcome.removeSubrange(range)

6 //welcomenowequals"hello"

NOTE

Youcanusetheinsert(_:at:),insert(contentsOf:at:),remove(at:),andremoveSubrange(_:)methodsonanytypethatconformstotheRangeReplaceableCollectionprotocol.ThisincludesString,asshownhere,aswellascollectiontypessuchasArray,Dictionary,andSet.

Substrings

Whenyougetasubstringfromastring—forexample,usingasubscriptoramethodlikeprefix(_:)—theresultisaninstanceofSubstring,notanotherstring.SubstringsinSwifthavemostofthesamemethodsasstrings,whichmeansyoucanworkwithsubstringsthesamewayyouworkwithstrings.However,unlikestrings,youusesubstringsforonlyashortamountoftimewhileperformingactionsonastring.Whenyou’rereadytostoretheresultforalongertime,youconvertthesubstringtoaninstanceofString.Forexample:

1 letgreeting="Hello,world!"

2 letindex=greeting.firstIndex(of:",")??greeting.endIndex

3 letbeginning=greeting[..<index]

4 //beginningis"Hello"

5

Page 101: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 //ConverttheresulttoaStringforlong-termstorage.

7 letnewString=String(beginning)

Likestrings,eachsubstringhasaregionofmemorywherethecharactersthatmakeupthesubstringarestored.Thedifferencebetweenstringsandsubstringsisthat,asaperformanceoptimization,asubstringcanreusepartofthememorythat’susedtostoretheoriginalstring,orpartofthememorythat’susedtostoreanothersubstring.(Stringshaveasimilaroptimization,butiftwostringssharememory,theyareequal.)Thisperformanceoptimizationmeansyoudon’thavetopaytheperformancecostofcopyingmemoryuntilyoumodifyeitherthestringorsubstring.Asmentionedabove,substringsaren’tsuitableforlong-termstorage—becausetheyreusethestorageoftheoriginalstring,theentireoriginalstringmustbekeptinmemoryaslongasanyofitssubstringsarebeingused.

Intheexampleabove,greetingisastring,whichmeansithasaregionofmemorywherethecharactersthatmakeupthestringarestored.Becausebeginningisasubstringofgreeting,itreusesthememorythatgreetinguses.Incontrast,newStringisastring—whenit’screatedfromthesubstring,ithasitsownstorage.Thefigurebelowshowstheserelationships:

NOTE

BothStringandSubstringconformtotheStringProtocolprotocol,whichmeansit’softenconvenientforstring-manipulationfunctionstoacceptaStringProtocolvalue.YoucancallsuchfunctionswitheitheraStringorSubstringvalue.

Page 102: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ComparingStrings

Swiftprovidesthreewaystocomparetextualvalues:stringandcharacterequality,prefixequality,andsuffixequality.

StringandCharacterEqualityStringandcharacterequalityischeckedwiththe“equalto”operator(==)andthe“notequalto”operator(!=),asdescribedinComparisonOperators:

1 letquotation="We'realotalike,youandI."

2 letsameQuotation="We'realotalike,youandI."

3 ifquotation==sameQuotation{

4 print("Thesetwostringsareconsideredequal")

5 }

6 //Prints"Thesetwostringsareconsideredequal"

TwoStringvalues(ortwoCharactervalues)areconsideredequaliftheirextendedgraphemeclustersarecanonicallyequivalent.Extendedgraphemeclustersarecanonicallyequivalentiftheyhavethesamelinguisticmeaningandappearance,evenifthey’recomposedfromdifferentUnicodescalarsbehindthescenes.

Forexample,LATINSMALLLETTEREWITHACUTE(U+00E9)iscanonicallyequivalenttoLATINSMALLLETTERE(U+0065)followedbyCOMBININGACUTEACCENT(U+0301).Bothoftheseextendedgraphemeclustersarevalidwaystorepresentthecharacteré,andsothey’reconsideredtobecanonicallyequivalent:

1 //"Voulez-vousuncafé?"usingLATINSMALLLETTEREWITHACUTE

2 leteAcuteQuestion="Voulez-vousuncaf\u{E9}?"

3

4 //"Voulez-vousuncafé?"usingLATINSMALLLETTEREand

COMBININGACUTEACCENT

Page 103: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 letcombinedEAcuteQuestion="Voulez-vousuncaf\u{65}\u{301}?"

6

7 ifeAcuteQuestion==combinedEAcuteQuestion{

8 print("Thesetwostringsareconsideredequal")

9 }

10 //Prints"Thesetwostringsareconsideredequal"

Conversely,LATINCAPITALLETTERA(U+0041,or"A"),asusedinEnglish,isnotequivalenttoCYRILLICCAPITALLETTERA(U+0410,or"А"),asusedinRussian.Thecharactersarevisuallysimilar,butdon’thavethesamelinguisticmeaning:

1 letlatinCapitalLetterA:Character="\u{41}"

2

3 letcyrillicCapitalLetterA:Character="\u{0410}"

4

5 iflatinCapitalLetterA!=cyrillicCapitalLetterA{

6 print("Thesetwocharactersarenotequivalent.")

7 }

8 //Prints"Thesetwocharactersarenotequivalent."

NOTE

StringandcharactercomparisonsinSwiftarenotlocale-sensitive.

PrefixandSuffixEqualityTocheckwhetherastringhasaparticularstringprefixorsuffix,callthestring’shasPrefix(_:)andhasSuffix(_:)methods,bothofwhichtakeasingleargumentoftypeStringandreturnaBooleanvalue.

TheexamplesbelowconsideranarrayofstringsrepresentingthescenelocationsfromthefirsttwoactsofShakespeare’sRomeoandJuliet:

Page 104: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letromeoAndJuliet=[

2 "Act1Scene1:Verona,Apublicplace",

3 "Act1Scene2:Capulet'smansion",

4 "Act1Scene3:AroominCapulet'smansion",

5 "Act1Scene4:AstreetoutsideCapulet'smansion",

6 "Act1Scene5:TheGreatHallinCapulet'smansion",

7 "Act2Scene1:OutsideCapulet'smansion",

8 "Act2Scene2:Capulet'sorchard",

9 "Act2Scene3:OutsideFriarLawrence'scell",

10 "Act2Scene4:AstreetinVerona",

11 "Act2Scene5:Capulet'smansion",

12 "Act2Scene6:FriarLawrence'scell"

13 ]

YoucanusethehasPrefix(_:)methodwiththeromeoAndJulietarraytocountthenumberofscenesinAct1oftheplay:

1 varact1SceneCount=0

2 forsceneinromeoAndJuliet{

3 ifscene.hasPrefix("Act1"){

4 act1SceneCount+=1

5 }

6 }

7 print("Thereare\(act1SceneCount)scenesinAct1")

8 //Prints"Thereare5scenesinAct1"

Similarly,usethehasSuffix(_:)methodtocountthenumberofscenesthattakeplaceinoraroundCapulet’smansionandFriarLawrence’scell:

1 varmansionCount=0

2 varcellCount=0

Page 105: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 forsceneinromeoAndJuliet{

4 ifscene.hasSuffix("Capulet'smansion"){

5 mansionCount+=1

6 }elseifscene.hasSuffix("FriarLawrence'scell"){

7 cellCount+=1

8 }

9 }

10 print("\(mansionCount)mansionscenes;\(cellCount)cell

scenes")

11 //Prints"6mansionscenes;2cellscenes"

NOTE

ThehasPrefix(_:)andhasSuffix(_:)methodsperformacharacter-by-charactercanonicalequivalencecomparisonbetweentheextendedgraphemeclustersineachstring,asdescribedinStringandCharacterEquality.

UnicodeRepresentationsofStrings

WhenaUnicodestringiswrittentoatextfileorsomeotherstorage,theUnicodescalarsinthatstringareencodedinoneofseveralUnicode-definedencodingforms.Eachformencodesthestringinsmallchunksknownascodeunits.TheseincludetheUTF-8encodingform(whichencodesastringas8-bitcodeunits),theUTF-16encodingform(whichencodesastringas16-bitcodeunits),andtheUTF-32encodingform(whichencodesastringas32-bitcodeunits).

SwiftprovidesseveraldifferentwaystoaccessUnicoderepresentationsofstrings.Youcaniterateoverthestringwithafor-instatement,toaccessitsindividualCharactervaluesasUnicodeextendedgraphemeclusters.ThisprocessisdescribedinWorkingwithCharacters.

Alternatively,accessaStringvalueinoneofthreeotherUnicode-compliant

Page 106: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

representations:

AcollectionofUTF-8codeunits(accessedwiththestring’sutf8property)

AcollectionofUTF-16codeunits(accessedwiththestring’sutf16property)

Acollectionof21-bitUnicodescalarvalues,equivalenttothestring’sUTF-32encodingform(accessedwiththestring’sunicodeScalarsproperty)

Eachexamplebelowshowsadifferentrepresentationofthefollowingstring,whichismadeupofthecharactersD,o,g,‼(DOUBLEEXCLAMATIONMARK,orUnicodescalarU+203C),andthecharacter( DOGFACE,orUnicodescalarU+1F436):

letdogString="Dog‼"

UTF-8RepresentationYoucanaccessaUTF-8representationofaStringbyiteratingoveritsutf8property.ThispropertyisoftypeString.UTF8View,whichisacollectionofunsigned8-bit(UInt8)values,oneforeachbyteinthestring’sUTF-8representation:

1 forcodeUnitindogString.utf8{

2 print("\(codeUnit)",terminator:"")

Page 107: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 }

4 print("")

5 //Prints"68111103226128188240159144182"

Intheexampleabove,thefirstthreedecimalcodeUnitvalues(68,111,103)representthecharactersD,o,andg,whoseUTF-8representationisthesameastheirASCIIrepresentation.ThenextthreedecimalcodeUnitvalues(226,128,188)areathree-byteUTF-8representationoftheDOUBLEEXCLAMATIONMARKcharacter.ThelastfourcodeUnitvalues(240,159,144,182)areafour-byteUTF-8representationoftheDOGFACEcharacter.

UTF-16RepresentationYoucanaccessaUTF-16representationofaStringbyiteratingoveritsutf16property.ThispropertyisoftypeString.UTF16View,whichisacollectionofunsigned16-bit(UInt16)values,oneforeach16-bitcodeunitinthestring’sUTF-16representation:

1 forcodeUnitindogString.utf16{

2 print("\(codeUnit)",terminator:"")

3 }

4 print("")

5 //Prints"6811110382525535756374"

Page 108: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Again,thefirstthreecodeUnitvalues(68,111,103)representthecharactersD,o,andg,whoseUTF-16codeunitshavethesamevaluesasinthestring’sUTF-8representation(becausetheseUnicodescalarsrepresentASCIIcharacters).

ThefourthcodeUnitvalue(8252)isadecimalequivalentofthehexadecimalvalue203C,whichrepresentstheUnicodescalarU+203CfortheDOUBLEEXCLAMATIONMARKcharacter.ThischaractercanberepresentedasasinglecodeunitinUTF-16.

ThefifthandsixthcodeUnitvalues(55357and56374)areaUTF-16surrogatepairrepresentationoftheDOGFACEcharacter.Thesevaluesareahigh-surrogatevalueofU+D83D(decimalvalue55357)andalow-surrogatevalueofU+DC36(decimalvalue56374).

UnicodeScalarRepresentationYoucanaccessaUnicodescalarrepresentationofaStringvaluebyiteratingoveritsunicodeScalarsproperty.ThispropertyisoftypeUnicodeScalarView,whichisacollectionofvaluesoftypeUnicodeScalar.

EachUnicodeScalarhasavaluepropertythatreturnsthescalar’s21-bitvalue,representedwithinaUInt32value:

1 forscalarindogString.unicodeScalars{

2 print("\(scalar.value)",terminator:"")

Page 109: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 }

4 print("")

5 //Prints"681111038252128054"

ThevaluepropertiesforthefirstthreeUnicodeScalarvalues(68,111,103)onceagainrepresentthecharactersD,o,andg.

ThefourthcodeUnitvalue(8252)isagainadecimalequivalentofthehexadecimalvalue203C,whichrepresentstheUnicodescalarU+203CfortheDOUBLEEXCLAMATIONMARKcharacter.

ThevaluepropertyofthefifthandfinalUnicodeScalar,128054,isadecimalequivalentofthehexadecimalvalue1F436,whichrepresentstheUnicodescalarU+1F436fortheDOGFACEcharacter.

Asanalternativetoqueryingtheirvalueproperties,eachUnicodeScalarvaluecanalsobeusedtoconstructanewStringvalue,suchaswithstringinterpolation:

1 forscalarindogString.unicodeScalars{

2 print("\(scalar)")

3 }

4 //D

5 //o

6 //g

7 //‼

8 //

Page 110: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

CollectionTypes

Swiftprovidesthreeprimarycollectiontypes,knownasarrays,sets,anddictionaries,forstoringcollectionsofvalues.Arraysareorderedcollectionsofvalues.Setsareunorderedcollectionsofuniquevalues.Dictionariesareunorderedcollectionsofkey-valueassociations.

Arrays,sets,anddictionariesinSwiftarealwaysclearaboutthetypesofvaluesandkeysthattheycanstore.Thismeansthatyoucannotinsertavalueofthewrongtypeintoacollectionbymistake.Italsomeansyoucanbeconfidentaboutthetypeofvaluesyouwillretrievefromacollection.

NOTE

Swift’sarray,set,anddictionarytypesareimplementedasgenericcollections.Formoreaboutgenerictypesandcollections,seeGenerics.

MutabilityofCollections

Ifyoucreateanarray,aset,oradictionary,andassignittoavariable,thecollectionthatiscreatedwillbemutable.Thismeansthatyoucanchange(ormutate)thecollectionafterit’screatedbyadding,removing,orchangingitemsinthecollection.Ifyouassignanarray,aset,oradictionarytoaconstant,that

Page 111: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

collectionisimmutable,anditssizeandcontentscannotbechanged.

NOTE

Itisgoodpracticetocreateimmutablecollectionsinallcaseswherethecollectiondoesnotneedtochange.DoingsomakesiteasierforyoutoreasonaboutyourcodeandenablestheSwiftcompilertooptimizetheperformanceofthecollectionsyoucreate.

Arrays

Anarraystoresvaluesofthesametypeinanorderedlist.Thesamevaluecanappearinanarraymultipletimesatdifferentpositions.

NOTE

Swift’sArraytypeisbridgedtoFoundation’sNSArrayclass.

FormoreinformationaboutusingArraywithFoundationandCocoa,seeBridgingBetweenArrayandNSArray.

ArrayTypeShorthandSyntaxThetypeofaSwiftarrayiswritteninfullasArray<Element>,whereElementisthetypeofvaluesthearrayisallowedtostore.Youcanalsowritethetypeofanarrayinshorthandformas[Element].Althoughthetwoformsarefunctionallyidentical,theshorthandformispreferredandisusedthroughoutthisguidewhenreferringtothetypeofanarray.

CreatinganEmptyArrayYoucancreateanemptyarrayofacertaintypeusinginitializersyntax:

1 varsomeInts=[Int]()

2 print("someIntsisoftype[Int]with\(someInts.count)

Page 112: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

items.")

3 //Prints"someIntsisoftype[Int]with0items."

NotethatthetypeofthesomeIntsvariableisinferredtobe[Int]fromthetypeoftheinitializer.

Alternatively,ifthecontextalreadyprovidestypeinformation,suchasafunctionargumentoranalreadytypedvariableorconstant,youcancreateanemptyarraywithanemptyarrayliteral,whichiswrittenas[](anemptypairofsquarebrackets):

1 someInts.append(3)

2 //someIntsnowcontains1valueoftypeInt

3 someInts=[]

4 //someIntsisnowanemptyarray,butisstilloftype[Int]

CreatinganArraywithaDefaultValueSwift’sArraytypealsoprovidesaninitializerforcreatinganarrayofacertainsizewithallofitsvaluessettothesamedefaultvalue.Youpassthisinitializeradefaultvalueoftheappropriatetype(calledrepeating):andthenumberoftimesthatvalueisrepeatedinthenewarray(calledcount):

1 varthreeDoubles=Array(repeating:0.0,count:3)

2 //threeDoublesisoftype[Double],andequals[0.0,0.0,0.0]

CreatinganArraybyAddingTwoArraysTogetherYoucancreateanewarraybyaddingtogethertwoexistingarrayswithcompatibletypeswiththeadditionoperator(+).Thenewarray’stypeisinferredfromthetypeofthetwoarraysyouaddtogether:

1 varanotherThreeDoubles=Array(repeating:2.5,count:3)

Page 113: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 //anotherThreeDoublesisoftype[Double],andequals[2.5,

2.5,2.5]

3

4 varsixDoubles=threeDoubles+anotherThreeDoubles

5 //sixDoublesisinferredas[Double],andequals[0.0,0.0,

0.0,2.5,2.5,2.5]

CreatinganArraywithanArrayLiteralYoucanalsoinitializeanarraywithanarrayliteral,whichisashorthandwaytowriteoneormorevaluesasanarraycollection.Anarrayliteraliswrittenasalistofvalues,separatedbycommas,surroundedbyapairofsquarebrackets:

[ value1 , value2 , value3 ]

TheexamplebelowcreatesanarraycalledshoppingListtostoreStringvalues:

1 varshoppingList:[String]=["Eggs","Milk"]

2 //shoppingListhasbeeninitializedwithtwoinitialitems

TheshoppingListvariableisdeclaredas“anarrayofstringvalues”,writtenas[String].BecausethisparticulararrayhasspecifiedavaluetypeofString,itisallowedtostoreStringvaluesonly.Here,theshoppingListarrayisinitializedwithtwoStringvalues("Eggs"and"Milk"),writtenwithinanarrayliteral.

NOTE

TheshoppingListarrayisdeclaredasavariable(withthevarintroducer)andnotaconstant(withtheletintroducer)becausemoreitemsareaddedtotheshoppinglistintheexamplesbelow.

Inthiscase,thearrayliteralcontainstwoStringvaluesandnothingelse.ThismatchesthetypeoftheshoppingListvariable’sdeclaration(anarraythatcanonlycontainStringvalues),andsotheassignmentofthearrayliteralispermittedasawaytoinitializeshoppingListwithtwoinitialitems.

Page 114: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThankstoSwift’stypeinference,youdon’thavetowritethetypeofthearrayifyou’reinitializingitwithanarrayliteralcontainingvaluesofthesametype.TheinitializationofshoppingListcouldhavebeenwritteninashorterforminstead:

varshoppingList=["Eggs","Milk"]

Becauseallvaluesinthearrayliteralareofthesametype,Swiftcaninferthat[String]isthecorrecttypetousefortheshoppingListvariable.

AccessingandModifyinganArrayYouaccessandmodifyanarraythroughitsmethodsandproperties,orbyusingsubscriptsyntax.

Tofindoutthenumberofitemsinanarray,checkitsread-onlycountproperty:

1 print("Theshoppinglistcontains\(shoppingList.count)

items.")

2 //Prints"Theshoppinglistcontains2items."

UsetheBooleanisEmptypropertyasashortcutforcheckingwhetherthecountpropertyisequalto0:

1 ifshoppingList.isEmpty{

2 print("Theshoppinglistisempty.")

3 }else{

4 print("Theshoppinglistisnotempty.")

5 }

6 //Prints"Theshoppinglistisnotempty."

Youcanaddanewitemtotheendofanarraybycallingthearray’sappend(_:)method:

1 shoppingList.append("Flour")

Page 115: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 //shoppingListnowcontains3items,andsomeoneismaking

pancakes

Alternatively,appendanarrayofoneormorecompatibleitemswiththeadditionassignmentoperator(+=):

1 shoppingList+=["BakingPowder"]

2 //shoppingListnowcontains4items

3 shoppingList+=["ChocolateSpread","Cheese","Butter"]

4 //shoppingListnowcontains7items

Retrieveavaluefromthearraybyusingsubscriptsyntax,passingtheindexofthevalueyouwanttoretrievewithinsquarebracketsimmediatelyafterthenameofthearray:

1 varfirstItem=shoppingList[0]

2 //firstItemisequalto"Eggs"

NOTE

Thefirstiteminthearrayhasanindexof0,not1.ArraysinSwiftarealwayszero-indexed.

Youcanusesubscriptsyntaxtochangeanexistingvalueatagivenindex:

1 shoppingList[0]="Sixeggs"

2 //thefirstiteminthelistisnowequalto"Sixeggs"rather

than"Eggs"

Whenyouusesubscriptsyntax,theindexyouspecifyneedstobevalid.Forexample,writingshoppingList[shoppingList.count]="Salt"totrytoappendanitemtotheendofthearrayresultsinaruntimeerror.

Youcanalsousesubscriptsyntaxtochangearangeofvaluesatonce,evenifthereplacementsetofvalueshasadifferentlengththantherangeyouarereplacing.Thefollowingexamplereplaces"ChocolateSpread","Cheese",and"Butter"

Page 116: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

with"Bananas"and"Apples":

1 shoppingList[4...6]=["Bananas","Apples"]

2 //shoppingListnowcontains6items

Toinsertanitemintothearrayataspecifiedindex,callthearray’sinsert(_:at:)method:

1 shoppingList.insert("MapleSyrup",at:0)

2 //shoppingListnowcontains7items

3 //"MapleSyrup"isnowthefirstiteminthelist

Thiscalltotheinsert(_:at:)methodinsertsanewitemwithavalueof"MapleSyrup"attheverybeginningoftheshoppinglist,indicatedbyanindexof0.

Similarly,youremoveanitemfromthearraywiththeremove(at:)method.Thismethodremovestheitematthespecifiedindexandreturnstheremoveditem(althoughyoucanignorethereturnedvalueifyoudonotneedit):

1 letmapleSyrup=shoppingList.remove(at:0)

2 //theitemthatwasatindex0hasjustbeenremoved

3 //shoppingListnowcontains6items,andnoMapleSyrup

4 //themapleSyrupconstantisnowequaltotheremoved"Maple

Syrup"string

NOTE

Ifyoutrytoaccessormodifyavalueforanindexthatisoutsideofanarray’sexistingbounds,youwilltriggeraruntimeerror.Youcancheckthatanindexisvalidbeforeusingitbycomparingittothearray’scountproperty.Thelargestvalidindexinanarrayiscount-1becausearraysareindexedfromzero—however,whencountis0(meaningthearrayisempty),therearenovalidindexes.

Anygapsinanarrayareclosedwhenanitemisremoved,andsothevalueatindex0isonceagainequalto"Sixeggs":

Page 117: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 firstItem=shoppingList[0]

2 //firstItemisnowequalto"Sixeggs"

Ifyouwanttoremovethefinalitemfromanarray,usetheremoveLast()methodratherthantheremove(at:)methodtoavoidtheneedtoquerythearray’scountproperty.Liketheremove(at:)method,removeLast()returnstheremoveditem:

1 letapples=shoppingList.removeLast()

2 //thelastiteminthearrayhasjustbeenremoved

3 //shoppingListnowcontains5items,andnoapples

4 //theapplesconstantisnowequaltotheremoved"Apples"

string

IteratingOveranArrayYoucaniterateovertheentiresetofvaluesinanarraywiththefor-inloop:

1 foriteminshoppingList{

2 print(item)

3 }

4 //Sixeggs

5 //Milk

6 //Flour

7 //BakingPowder

8 //Bananas

Ifyouneedtheintegerindexofeachitemaswellasitsvalue,usetheenumerated()methodtoiterateoverthearrayinstead.Foreachiteminthearray,theenumerated()methodreturnsatuplecomposedofanintegerandtheitem.Theintegersstartatzeroandcountupbyoneforeachitem;ifyouenumerateoverawholearray,theseintegersmatchtheitems’indices.Youcandecomposethetupleintotemporaryconstantsorvariablesaspartoftheiteration:

Page 118: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 for(index,value)inshoppingList.enumerated(){

2 print("Item\(index+1):\(value)")

3 }

4 //Item1:Sixeggs

5 //Item2:Milk

6 //Item3:Flour

7 //Item4:BakingPowder

8 //Item5:Bananas

Formoreaboutthefor-inloop,seeFor-InLoops.

Sets

Asetstoresdistinctvaluesofthesametypeinacollectionwithnodefinedordering.Youcanuseasetinsteadofanarraywhentheorderofitemsisnotimportant,orwhenyouneedtoensurethatanitemonlyappearsonce.

NOTE

Swift’sSettypeisbridgedtoFoundation’sNSSetclass.

FormoreinformationaboutusingSetwithFoundationandCocoa,seeBridgingBetweenSetandNSSet.

HashValuesforSetTypesAtypemustbehashableinordertobestoredinaset—thatis,thetypemustprovideawaytocomputeahashvalueforitself.AhashvalueisanIntvaluethatisthesameforallobjectsthatcompareequally,suchthatifa==b,itfollowsthata.hashValue==b.hashValue.

AllofSwift’sbasictypes(suchasString,Int,Double,andBool)arehashablebydefault,andcanbeusedassetvaluetypesordictionarykeytypes.Enumeration

Page 119: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

casevalueswithoutassociatedvalues(asdescribedinEnumerations)arealsohashablebydefault.

NOTE

YoucanuseyourowncustomtypesassetvaluetypesordictionarykeytypesbymakingthemconformtotheHashableprotocolfromSwift’sstandardlibrary.TypesthatconformtotheHashableprotocolmustprovideagettableIntpropertycalledhashValue.Thevaluereturnedbyatype’shashValuepropertyisnotrequiredtobethesameacrossdifferentexecutionsofthesameprogram,orindifferentprograms.

BecausetheHashableprotocolconformstoEquatable,conformingtypesmustalsoprovideanimplementationoftheequalsoperator(==).TheEquatableprotocolrequiresanyconformingimplementationof==tobeanequivalencerelation.Thatis,animplementationof==mustsatisfythefollowingthreeconditions,forallvaluesa,b,andc:

a==a(Reflexivity)

a==bimpliesb==a(Symmetry)

a==b&&b==cimpliesa==c(Transitivity)

Formoreinformationaboutconformingtoprotocols,seeProtocols.

SetTypeSyntaxThetypeofaSwiftsetiswrittenasSet<Element>,whereElementisthetypethatthesetisallowedtostore.Unlikearrays,setsdonothaveanequivalentshorthandform.

CreatingandInitializinganEmptySetYoucancreateanemptysetofacertaintypeusinginitializersyntax:

1 varletters=Set<Character>()

2 print("lettersisoftypeSet<Character>with\(letters.count)

items.")

3 //Prints"lettersisoftypeSet<Character>with0items."

NOTE

Page 120: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThetypeofthelettersvariableisinferredtobeSet<Character>,fromthetypeoftheinitializer.

Alternatively,ifthecontextalreadyprovidestypeinformation,suchasafunctionargumentoranalreadytypedvariableorconstant,youcancreateanemptysetwithanemptyarrayliteral:

1 letters.insert("a")

2 //lettersnowcontains1valueoftypeCharacter

3 letters=[]

4 //lettersisnowanemptyset,butisstilloftype

Set<Character>

CreatingaSetwithanArrayLiteralYoucanalsoinitializeasetwithanarrayliteral,asashorthandwaytowriteoneormorevaluesasasetcollection.

TheexamplebelowcreatesasetcalledfavoriteGenrestostoreStringvalues:

1 varfavoriteGenres:Set<String>=["Rock","Classical","Hip

hop"]

2 //favoriteGenreshasbeeninitializedwiththreeinitialitems

ThefavoriteGenresvariableisdeclaredas“asetofStringvalues”,writtenasSet<String>.BecausethisparticularsethasspecifiedavaluetypeofString,itisonlyallowedtostoreStringvalues.Here,thefavoriteGenressetisinitializedwiththreeStringvalues("Rock","Classical",and"Hiphop"),writtenwithinanarrayliteral.

NOTE

ThefavoriteGenressetisdeclaredasavariable(withthevarintroducer)andnotaconstant(withtheletintroducer)becauseitemsareaddedandremovedintheexamplesbelow.

Page 121: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Asettypecannotbeinferredfromanarrayliteralalone,sothetypeSetmustbeexplicitlydeclared.However,becauseofSwift’stypeinference,youdon’thavetowritethetypeoftheset’selementsifyou’reinitializingitwithanarrayliteralthatcontainsvaluesofjustonetype.TheinitializationoffavoriteGenrescouldhavebeenwritteninashorterforminstead:

varfavoriteGenres:Set=["Rock","Classical","Hiphop"]

Becauseallvaluesinthearrayliteralareofthesametype,SwiftcaninferthatSet<String>isthecorrecttypetouseforthefavoriteGenresvariable.

AccessingandModifyingaSetYouaccessandmodifyasetthroughitsmethodsandproperties.

Tofindoutthenumberofitemsinaset,checkitsread-onlycountproperty:

1 print("Ihave\(favoriteGenres.count)favoritemusicgenres.")

2 //Prints"Ihave3favoritemusicgenres."

UsetheBooleanisEmptypropertyasashortcutforcheckingwhetherthecountpropertyisequalto0:

1 iffavoriteGenres.isEmpty{

2 print("Asfarasmusicgoes,I'mnotpicky.")

3 }else{

4 print("Ihaveparticularmusicpreferences.")

5 }

6 //Prints"Ihaveparticularmusicpreferences."

Youcanaddanewitemintoasetbycallingtheset’sinsert(_:)method:

1 favoriteGenres.insert("Jazz")

2 //favoriteGenresnowcontains4items

Page 122: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youcanremoveanitemfromasetbycallingtheset’sremove(_:)method,whichremovestheitemifit’samemberoftheset,andreturnstheremovedvalue,orreturnsnilifthesetdidnotcontainit.Alternatively,allitemsinasetcanberemovedwithitsremoveAll()method.

1 ifletremovedGenre=favoriteGenres.remove("Rock"){

2 print("\(removedGenre)?I'moverit.")

3 }else{

4 print("Inevermuchcaredforthat.")

5 }

6 //Prints"Rock?I'moverit."

Tocheckwhetherasetcontainsaparticularitem,usethecontains(_:)method.

1 iffavoriteGenres.contains("Funk"){

2 print("Igetuponthegoodfoot.")

3 }else{

4 print("It'stoofunkyinhere.")

5 }

6 //Prints"It'stoofunkyinhere."

IteratingOveraSetYoucaniterateoverthevaluesinasetwithafor-inloop.

1 forgenreinfavoriteGenres{

2 print("\(genre)")

3 }

4 //Classical

5 //Jazz

6 //Hiphop

Page 123: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Formoreaboutthefor-inloop,seeFor-InLoops.

Swift’sSettypedoesnothaveadefinedordering.Toiterateoverthevaluesofasetinaspecificorder,usethesorted()method,whichreturnstheset’selementsasanarraysortedusingthe<operator.

1 forgenreinfavoriteGenres.sorted(){

2 print("\(genre)")

3 }

4 //Classical

5 //Hiphop

6 //Jazz

PerformingSetOperations

Youcanefficientlyperformfundamentalsetoperations,suchascombiningtwosetstogether,determiningwhichvaluestwosetshaveincommon,ordeterminingwhethertwosetscontainall,some,ornoneofthesamevalues.

FundamentalSetOperationsTheillustrationbelowdepictstwosets—aandb—withtheresultsofvarioussetoperationsrepresentedbytheshadedregions.

Page 124: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Usetheintersection(_:)methodtocreateanewsetwithonlythevaluescommontobothsets.

UsethesymmetricDifference(_:)methodtocreateanewsetwithvaluesineitherset,butnotboth.

Usetheunion(_:)methodtocreateanewsetwithallofthevaluesinbothsets.

Usethesubtracting(_:)methodtocreateanewsetwithvaluesnotinthespecifiedset.

1 letoddDigits:Set=[1,3,5,7,9]

2 letevenDigits:Set=[0,2,4,6,8]

3 letsingleDigitPrimeNumbers:Set=[2,3,5,7]

4

5 oddDigits.union(evenDigits).sorted()

Page 125: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 //[0,1,2,3,4,5,6,7,8,9]

7 oddDigits.intersection(evenDigits).sorted()

8 //[]

9 oddDigits.subtracting(singleDigitPrimeNumbers).sorted()

10 //[1,9]

11 oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()

12 //[1,2,9]

SetMembershipandEqualityTheillustrationbelowdepictsthreesets—a,bandc—withoverlappingregionsrepresentingelementssharedamongsets.Setaisasupersetofsetb,becauseacontainsallelementsinb.Conversely,setbisasubsetofseta,becauseallelementsinbarealsocontainedbya.Setbandsetcaredisjointwithoneanother,becausetheysharenoelementsincommon.

Usethe“isequal”operator(==)todeterminewhethertwosetscontainallofthesamevalues.

Page 126: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

UsetheisSubset(of:)methodtodeterminewhetherallofthevaluesofasetarecontainedinthespecifiedset.

UsetheisSuperset(of:)methodtodeterminewhetherasetcontainsallofthevaluesinaspecifiedset.

UsetheisStrictSubset(of:)orisStrictSuperset(of:)methodstodeterminewhetherasetisasubsetorsuperset,butnotequalto,aspecifiedset.

UsetheisDisjoint(with:)methodtodeterminewhethertwosetshavenovaluesincommon.

1 lethouseAnimals:Set=["" ," "]

2 letfarmAnimals:Set=[" ","" ,"" ,"" ," "]

3 letcityAnimals:Set=["" ," "]

4

5 houseAnimals.isSubset(of:farmAnimals)

6 //true

7 farmAnimals.isSuperset(of:houseAnimals)

8 //true

9 farmAnimals.isDisjoint(with:cityAnimals)

10 //true

Dictionaries

Adictionarystoresassociationsbetweenkeysofthesametypeandvaluesofthesametypeinacollectionwithnodefinedordering.Eachvalueisassociatedwithauniquekey,whichactsasanidentifierforthatvaluewithinthedictionary.Unlikeitemsinanarray,itemsinadictionarydonothaveaspecifiedorder.Youuseadictionarywhenyouneedtolookupvaluesbasedontheiridentifier,inmuchthesamewaythatareal-worlddictionaryisusedtolookupthedefinitionforaparticularword.

Page 127: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Swift’sDictionarytypeisbridgedtoFoundation’sNSDictionaryclass.

FormoreinformationaboutusingDictionarywithFoundationandCocoa,seeBridgingBetweenDictionaryandNSDictionary.

DictionaryTypeShorthandSyntaxThetypeofaSwiftdictionaryiswritteninfullasDictionary<Key,Value>,whereKeyisthetypeofvaluethatcanbeusedasadictionarykey,andValueisthetypeofvaluethatthedictionarystoresforthosekeys.

NOTE

AdictionaryKeytypemustconformtotheHashableprotocol,likeaset’svaluetype.

Youcanalsowritethetypeofadictionaryinshorthandformas[Key:Value].Althoughthetwoformsarefunctionallyidentical,theshorthandformispreferredandisusedthroughoutthisguidewhenreferringtothetypeofadictionary.

CreatinganEmptyDictionaryAswitharrays,youcancreateanemptyDictionaryofacertaintypebyusinginitializersyntax:

1 varnamesOfIntegers=[Int:String]()

2 //namesOfIntegersisanempty[Int:String]dictionary

Thisexamplecreatesanemptydictionaryoftype[Int:String]tostorehuman-readablenamesofintegervalues.ItskeysareoftypeInt,anditsvaluesareoftypeString.

Ifthecontextalreadyprovidestypeinformation,youcancreateanemptydictionarywithanemptydictionaryliteral,whichiswrittenas[:](acoloninsideapairofsquarebrackets):

Page 128: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 namesOfIntegers[16]="sixteen"

2 //namesOfIntegersnowcontains1key-valuepair

3 namesOfIntegers=[:]

4 //namesOfIntegersisonceagainanemptydictionaryoftype

[Int:String]

CreatingaDictionarywithaDictionaryLiteralYoucanalsoinitializeadictionarywithadictionaryliteral,whichhasasimilarsyntaxtothearrayliteralseenearlier.Adictionaryliteralisashorthandwaytowriteoneormorekey-valuepairsasaDictionarycollection.

Akey-valuepairisacombinationofakeyandavalue.Inadictionaryliteral,thekeyandvalueineachkey-valuepairareseparatedbyacolon.Thekey-valuepairsarewrittenasalist,separatedbycommas,surroundedbyapairofsquarebrackets:

[ key1 : value1 , key2 : value2 , key3 : value3 ]

Theexamplebelowcreatesadictionarytostorethenamesofinternationalairports.Inthisdictionary,thekeysarethree-letterInternationalAirTransportAssociationcodes,andthevaluesareairportnames:

varairports:[String:String]=["YYZ":"TorontoPearson",

"DUB":"Dublin"]

Theairportsdictionaryisdeclaredashavingatypeof[String:String],whichmeans“aDictionarywhosekeysareoftypeString,andwhosevaluesarealsooftypeString”.

NOTE

Theairportsdictionaryisdeclaredasavariable(withthevarintroducer),andnotaconstant(withtheletintroducer),becausemoreairportsareaddedtothedictionaryintheexamplesbelow.

Page 129: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theairportsdictionaryisinitializedwithadictionaryliteralcontainingtwokey-valuepairs.Thefirstpairhasakeyof"YYZ"andavalueof"TorontoPearson".Thesecondpairhasakeyof"DUB"andavalueof"Dublin".

ThisdictionaryliteralcontainstwoString:Stringpairs.Thiskey-valuetypematchesthetypeoftheairportsvariabledeclaration(adictionarywithonlyStringkeys,andonlyStringvalues),andsotheassignmentofthedictionaryliteralispermittedasawaytoinitializetheairportsdictionarywithtwoinitialitems.

Aswitharrays,youdon’thavetowritethetypeofthedictionaryifyou’reinitializingitwithadictionaryliteralwhosekeysandvalueshaveconsistenttypes.Theinitializationofairportscouldhavebeenwritteninashorterforminstead:

varairports=["YYZ":"TorontoPearson","DUB":"Dublin"]

Becauseallkeysintheliteralareofthesametypeaseachother,andlikewiseallvaluesareofthesametypeaseachother,Swiftcaninferthat[String:String]isthecorrecttypetousefortheairportsdictionary.

AccessingandModifyingaDictionaryYouaccessandmodifyadictionarythroughitsmethodsandproperties,orbyusingsubscriptsyntax.

Aswithanarray,youfindoutthenumberofitemsinaDictionarybycheckingitsread-onlycountproperty:

1 print("Theairportsdictionarycontains\(airports.count)

items.")

2 //Prints"Theairportsdictionarycontains2items."

UsetheBooleanisEmptypropertyasashortcutforcheckingwhetherthecountpropertyisequalto0:

Page 130: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 ifairports.isEmpty{

2 print("Theairportsdictionaryisempty.")

3 }else{

4 print("Theairportsdictionaryisnotempty.")

5 }

6 //Prints"Theairportsdictionaryisnotempty."

Youcanaddanewitemtoadictionarywithsubscriptsyntax.Useanewkeyoftheappropriatetypeasthesubscriptindex,andassignanewvalueoftheappropriatetype:

1 airports["LHR"]="London"

2 //theairportsdictionarynowcontains3items

Youcanalsousesubscriptsyntaxtochangethevalueassociatedwithaparticularkey:

1 airports["LHR"]="LondonHeathrow"

2 //thevaluefor"LHR"hasbeenchangedto"LondonHeathrow"

Asanalternativetosubscripting,useadictionary’supdateValue(_:forKey:)methodtosetorupdatethevalueforaparticularkey.Likethesubscriptexamplesabove,theupdateValue(_:forKey:)methodsetsavalueforakeyifnoneexists,orupdatesthevalueifthatkeyalreadyexists.Unlikeasubscript,however,theupdateValue(_:forKey:)methodreturnstheoldvalueafterperforminganupdate.Thisenablesyoutocheckwhetherornotanupdatetookplace.

TheupdateValue(_:forKey:)methodreturnsanoptionalvalueofthedictionary’svaluetype.ForadictionarythatstoresStringvalues,forexample,themethodreturnsavalueoftypeString?,or“optionalString”.Thisoptionalvaluecontainstheoldvalueforthatkeyifoneexistedbeforetheupdate,ornilifnovalueexisted:

1 ifletoldValue=airports.updateValue("DublinAirport",

Page 131: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

forKey:"DUB"){

2 print("TheoldvalueforDUBwas\(oldValue).")

3 }

4 //Prints"TheoldvalueforDUBwasDublin."

Youcanalsousesubscriptsyntaxtoretrieveavaluefromthedictionaryforaparticularkey.Becauseitispossibletorequestakeyforwhichnovalueexists,adictionary’ssubscriptreturnsanoptionalvalueofthedictionary’svaluetype.Ifthedictionarycontainsavaluefortherequestedkey,thesubscriptreturnsanoptionalvaluecontainingtheexistingvalueforthatkey.Otherwise,thesubscriptreturnsnil:

1 ifletairportName=airports["DUB"]{

2 print("Thenameoftheairportis\(airportName).")

3 }else{

4 print("Thatairportisnotintheairportsdictionary.")

5 }

6 //Prints"ThenameoftheairportisDublinAirport."

Youcanusesubscriptsyntaxtoremoveakey-valuepairfromadictionarybyassigningavalueofnilforthatkey:

1 airports["APL"]="AppleInternational"

2 //"AppleInternational"isnottherealairportforAPL,so

deleteit

3 airports["APL"]=nil

4 //APLhasnowbeenremovedfromthedictionary

Alternatively,removeakey-valuepairfromadictionarywiththeremoveValue(forKey:)method.Thismethodremovesthekey-valuepairifitexistsandreturnstheremovedvalue,orreturnsnilifnovalueexisted:

1 ifletremovedValue=airports.removeValue(forKey:"DUB"){

Page 132: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 print("Theremovedairport'snameis\(removedValue).")

3 }else{

4 print("Theairportsdictionarydoesnotcontainavaluefor

DUB.")

5 }

6 //Prints"Theremovedairport'snameisDublinAirport."

IteratingOveraDictionaryYoucaniterateoverthekey-valuepairsinadictionarywithafor-inloop.Eachiteminthedictionaryisreturnedasa(key,value)tuple,andyoucandecomposethetuple’smembersintotemporaryconstantsorvariablesaspartoftheiteration:

1 for(airportCode,airportName)inairports{

2 print("\(airportCode):\(airportName)")

3 }

4 //LHR:LondonHeathrow

5 //YYZ:TorontoPearson

Formoreaboutthefor-inloop,seeFor-InLoops.

Youcanalsoretrieveaniterablecollectionofadictionary’skeysorvaluesbyaccessingitskeysandvaluesproperties:

1 forairportCodeinairports.keys{

2 print("Airportcode:\(airportCode)")

3 }

4 //Airportcode:LHR

5 //Airportcode:YYZ

6

7 forairportNameinairports.values{

Page 133: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 print("Airportname:\(airportName)")

9 }

10 //Airportname:LondonHeathrow

11 //Airportname:TorontoPearson

Ifyouneedtouseadictionary’skeysorvalueswithanAPIthattakesanArrayinstance,initializeanewarraywiththekeysorvaluesproperty:

1 letairportCodes=[String](airports.keys)

2 //airportCodesis["LHR","YYZ"]

3

4 letairportNames=[String](airports.values)

5 //airportNamesis["LondonHeathrow","TorontoPearson"]

Swift’sDictionarytypedoesnothaveadefinedordering.Toiterateoverthekeysorvaluesofadictionaryinaspecificorder,usethesorted()methodonitskeysorvaluesproperty.

Page 134: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ControlFlow

Swiftprovidesavarietyofcontrolflowstatements.Theseincludewhileloopstoperformataskmultipletimes;if,guard,andswitchstatementstoexecutedifferentbranchesofcodebasedoncertainconditions;andstatementssuchasbreakandcontinuetotransfertheflowofexecutiontoanotherpointinyourcode.

Swiftalsoprovidesafor-inloopthatmakesiteasytoiterateoverarrays,dictionaries,ranges,strings,andothersequences.

Swift’sswitchstatementisconsiderablymorepowerfulthanitscounterpartinmanyC-likelanguages.Casescanmatchmanydifferentpatterns,includingintervalmatches,tuples,andcaststoaspecifictype.Matchedvaluesinaswitchcasecanbeboundtotemporaryconstantsorvariablesforusewithinthecase’sbody,andcomplexmatchingconditionscanbeexpressedwithawhereclauseforeachcase.

For-InLoops

Youusethefor-inlooptoiterateoverasequence,suchasitemsinanarray,rangesofnumbers,orcharactersinastring.

Thisexampleusesafor-inlooptoiterateovertheitemsinanarray:

1 letnames=["Anna","Alex","Brian","Jack"]

2 fornameinnames{

3 print("Hello,\(name)!")

4 }

5 //Hello,Anna!

6 //Hello,Alex!

7 //Hello,Brian!

Page 135: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 //Hello,Jack!

Youcanalsoiterateoveradictionarytoaccessitskey-valuepairs.Eachiteminthedictionaryisreturnedasa(key,value)tuplewhenthedictionaryisiterated,andyoucandecomposethe(key,value)tuple’smembersasexplicitlynamedconstantsforusewithinthebodyofthefor-inloop.Inthecodeexamplebelow,thedictionary’skeysaredecomposedintoaconstantcalledanimalName,andthedictionary’svaluesaredecomposedintoaconstantcalledlegCount.

1 letnumberOfLegs=["spider":8,"ant":6,"cat":4]

2 for(animalName,legCount)innumberOfLegs{

3 print("\(animalName)shave\(legCount)legs")

4 }

5 //catshave4legs

6 //antshave6legs

7 //spidershave8legs

ThecontentsofaDictionaryareinherentlyunordered,anditeratingoverthemdoesnotguaranteetheorderinwhichtheywillberetrieved.Inparticular,theorderyouinsertitemsintoaDictionarydoesn’tdefinetheordertheyareiterated.Formoreaboutarraysanddictionaries,seeCollectionTypes.

Youcanalsousefor-inloopswithnumericranges.Thisexampleprintsthefirstfewentriesinafive-timestable:

1 forindexin1...5{

2 print("\(index)times5is\(index*5)")

3 }

4 //1times5is5

5 //2times5is10

6 //3times5is15

7 //4times5is20

8 //5times5is25

Page 136: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thesequencebeingiteratedoverisarangeofnumbersfrom1to5,inclusive,asindicatedbytheuseoftheclosedrangeoperator(...).Thevalueofindexissettothefirstnumberintherange(1),andthestatementsinsidetheloopareexecuted.Inthiscase,theloopcontainsonlyonestatement,whichprintsanentryfromthefive-timestableforthecurrentvalueofindex.Afterthestatementisexecuted,thevalueofindexisupdatedtocontainthesecondvalueintherange(2),andtheprint(_:separator:terminator:)functioniscalledagain.Thisprocesscontinuesuntiltheendoftherangeisreached.

Intheexampleabove,indexisaconstantwhosevalueisautomaticallysetatthestartofeachiterationoftheloop.Assuch,indexdoesnothavetobedeclaredbeforeitisused.Itisimplicitlydeclaredsimplybyitsinclusionintheloopdeclaration,withouttheneedforaletdeclarationkeyword.

Ifyoudon’tneedeachvaluefromasequence,youcanignorethevaluesbyusinganunderscoreinplaceofavariablename.

1 letbase=3

2 letpower=10

3 varanswer=1

4 for_in1...power{

5 answer*=base

6 }

7 print("\(base)tothepowerof\(power)is\(answer)")

8 //Prints"3tothepowerof10is59049"

Theexampleabovecalculatesthevalueofonenumbertothepowerofanother(inthiscase,3tothepowerof10).Itmultipliesastartingvalueof1(thatis,3tothepowerof0)by3,tentimes,usingaclosedrangethatstartswith1andendswith10.Forthiscalculation,theindividualcountervalueseachtimethroughtheloopareunnecessary—thecodesimplyexecutestheloopthecorrectnumberoftimes.Theunderscorecharacter(_)usedinplaceofaloopvariablecausestheindividualvaluestobeignoredanddoesnotprovideaccesstothecurrentvalueduringeachiterationoftheloop.

Insomesituations,youmightnotwanttouseclosedranges,whichincludeboth

Page 137: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

endpoints.Considerdrawingthetickmarksforeveryminuteonawatchface.Youwanttodraw60tickmarks,startingwiththe0minute.Usethehalf-openrangeoperator(..<)toincludethelowerboundbutnottheupperbound.Formoreaboutranges,seeRangeOperators.

1 letminutes=60

2 fortickMarkin0..<minutes{

3 //renderthetickmarkeachminute(60times)

4 }

SomeusersmightwantfewertickmarksintheirUI.Theycouldpreferonemarkevery5minutesinstead.Usethestride(from:to:by:)functiontoskiptheunwantedmarks.

1 letminuteInterval=5

2 fortickMarkinstride(from:0,to:minutes,by:

minuteInterval){

3 //renderthetickmarkevery5minutes(0,5,10,15...

45,50,55)

4 }

Closedrangesarealsoavailable,byusingstride(from:through:by:)instead:

1 lethours=12

2 lethourInterval=3

3 fortickMarkinstride(from:3,through:hours,by:

hourInterval){

4 //renderthetickmarkevery3hours(3,6,9,12)

5 }

WhileLoops

Page 138: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Awhileloopperformsasetofstatementsuntilaconditionbecomesfalse.Thesekindsofloopsarebestusedwhenthenumberofiterationsisnotknownbeforethefirstiterationbegins.Swiftprovidestwokindsofwhileloops:

whileevaluatesitsconditionatthestartofeachpassthroughtheloop.

repeat-whileevaluatesitsconditionattheendofeachpassthroughtheloop.

WhileAwhileloopstartsbyevaluatingasinglecondition.Iftheconditionistrue,asetofstatementsisrepeateduntiltheconditionbecomesfalse.

Here’sthegeneralformofawhileloop:

while condition {

statements

}

ThisexampleplaysasimplegameofSnakesandLadders(alsoknownasChutesandLadders):

Page 139: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Therulesofthegameareasfollows:

Theboardhas25squares,andtheaimistolandonorbeyondsquare25.

Theplayer’sstartingsquareis“squarezero”,whichisjustoffthebottom-leftcorneroftheboard.

Eachturn,yourollasix-sideddiceandmovebythatnumberofsquares,followingthehorizontalpathindicatedbythedottedarrowabove.

Ifyourturnendsatthebottomofaladder,youmoveupthatladder.

Ifyourturnendsattheheadofasnake,youmovedownthatsnake.

ThegameboardisrepresentedbyanarrayofIntvalues.ItssizeisbasedonaconstantcalledfinalSquare,whichisusedtoinitializethearrayandalsotocheckforawinconditionlaterintheexample.Becausetheplayersstartofftheboard,on“squarezero”,theboardisinitializedwith26zeroIntvalues,not25.

1 letfinalSquare=25

2 varboard=[Int](repeating:0,count:finalSquare+1)

Somesquaresarethensettohavemorespecificvaluesforthesnakesandladders.Squareswithaladderbasehaveapositivenumbertomoveyouuptheboard,whereassquareswithasnakeheadhaveanegativenumbertomoveyoubackdowntheboard.

1 board[03]=+08;board[06]=+11;board[09]=+09;board[10]=

+02

2 board[14]=-10;board[19]=-11;board[22]=-02;board[24]=

-08

Square3containsthebottomofaladderthatmovesyouuptosquare11.Torepresentthis,board[03]isequalto+08,whichisequivalenttoanintegervalueof8(thedifferencebetween3and11).Toalignthevaluesandstatements,theunaryplusoperator(+i)isexplicitlyusedwiththeunaryminusoperator(-i)andnumberslowerthan10arepaddedwithzeros.(Neitherstylistictechniqueis

Page 140: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

strictlynecessary,buttheyleadtoneatercode.)

1 varsquare=0

2 vardiceRoll=0

3 whilesquare<finalSquare{

4 //rollthedice

5 diceRoll+=1

6 ifdiceRoll==7{diceRoll=1}

7 //movebytherolledamount

8 square+=diceRoll

9 ifsquare<board.count{

10 //ifwe'restillontheboard,moveupordownfora

snakeoraladder

11 square+=board[square]

12 }

13 }

14 print("Gameover!")

Theexampleaboveusesaverysimpleapproachtodicerolling.Insteadofgeneratingarandomnumber,itstartswithadiceRollvalueof0.Eachtimethroughthewhileloop,diceRollisincrementedbyoneandisthencheckedtoseewhetherithasbecometoolarge.Wheneverthisreturnvalueequals7,thedicerollhasbecometoolargeandisresettoavalueof1.TheresultisasequenceofdiceRollvaluesthatisalways1,2,3,4,5,6,1,2andsoon.

Afterrollingthedice,theplayermovesforwardbydiceRollsquares.It’spossiblethatthedicerollmayhavemovedtheplayerbeyondsquare25,inwhichcasethegameisover.Tocopewiththisscenario,thecodechecksthatsquareislessthantheboardarray’scountproperty.Ifsquareisvalid,thevaluestoredinboard[square]isaddedtothecurrentsquarevaluetomovetheplayerupordownanyladdersorsnakes.

NOTE

Page 141: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Ifthischeckisnotperformed,board[square]mighttrytoaccessavalueoutsidetheboundsoftheboardarray,whichwouldtriggeraruntimeerror.

Thecurrentwhileloopexecutionthenends,andtheloop’sconditionischeckedtoseeiftheloopshouldbeexecutedagain.Iftheplayerhasmovedonorbeyondsquarenumber25,theloop’sconditionevaluatestofalseandthegameends.

Awhileloopisappropriateinthiscase,becausethelengthofthegameisnotclearatthestartofthewhileloop.Instead,theloopisexecuteduntilaparticularconditionissatisfied.

Repeat-WhileTheothervariationofthewhileloop,knownastherepeat-whileloop,performsasinglepassthroughtheloopblockfirst,beforeconsideringtheloop’scondition.Itthencontinuestorepeattheloopuntiltheconditionisfalse.

NOTE

Therepeat-whileloopinSwiftisanalogoustoado-whileloopinotherlanguages.

Here’sthegeneralformofarepeat-whileloop:

repeat{

statements

}while condition

Here’stheSnakesandLaddersexampleagain,writtenasarepeat-whileloopratherthanawhileloop.ThevaluesoffinalSquare,board,square,anddiceRollareinitializedinexactlythesamewayaswithawhileloop.

1 letfinalSquare=25

2 varboard=[Int](repeating:0,count:finalSquare+1)

3 board[03]=+08;board[06]=+11;board[09]=+09;board[10]=

+02

Page 142: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 board[14]=-10;board[19]=-11;board[22]=-02;board[24]=

-08

5 varsquare=0

6 vardiceRoll=0

Inthisversionofthegame,thefirstactionintheloopistocheckforaladderorasnake.Noladderontheboardtakestheplayerstraighttosquare25,andsoitisn’tpossibletowinthegamebymovingupaladder.Therefore,it’ssafetocheckforasnakeoraladderasthefirstactionintheloop.

Atthestartofthegame,theplayerison“squarezero”.board[0]alwaysequals0andhasnoeffect.

1 repeat{

2 //moveupordownforasnakeorladder

3 square+=board[square]

4 //rollthedice

5 diceRoll+=1

6 ifdiceRoll==7{diceRoll=1}

7 //movebytherolledamount

8 square+=diceRoll

9 }whilesquare<finalSquare

10 print("Gameover!")

Afterthecodechecksforsnakesandladders,thediceisrolledandtheplayerismovedforwardbydiceRollsquares.Thecurrentloopexecutionthenends.

Theloop’scondition(whilesquare<finalSquare)isthesameasbefore,butthistimeit’snotevaluateduntiltheendofthefirstrunthroughtheloop.Thestructureoftherepeat-whileloopisbettersuitedtothisgamethanthewhileloopinthepreviousexample.Intherepeat-whileloopabove,square+=board[square]isalwaysexecutedimmediatelyaftertheloop’swhileconditionconfirmsthatsquareisstillontheboard.Thisbehaviorremovestheneedforthearrayboundscheckseeninthewhileloopversionofthegamedescribedearlier.

Page 143: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ConditionalStatements

Itisoftenusefultoexecutedifferentpiecesofcodebasedoncertainconditions.Youmightwanttorunanextrapieceofcodewhenanerroroccurs,ortodisplayamessagewhenavaluebecomestoohighortoolow.Todothis,youmakepartsofyourcodeconditional.

Swiftprovidestwowaystoaddconditionalbranchestoyourcode:theifstatementandtheswitchstatement.Typically,youusetheifstatementtoevaluatesimpleconditionswithonlyafewpossibleoutcomes.Theswitchstatementisbettersuitedtomorecomplexconditionswithmultiplepossiblepermutationsandisusefulinsituationswherepatternmatchingcanhelpselectanappropriatecodebranchtoexecute.

IfInitssimplestform,theifstatementhasasingleifcondition.Itexecutesasetofstatementsonlyifthatconditionistrue.

1 vartemperatureInFahrenheit=30

2 iftemperatureInFahrenheit<=32{

3 print("It'sverycold.Considerwearingascarf.")

4 }

5 //Prints"It'sverycold.Considerwearingascarf."

Theexampleabovecheckswhetherthetemperatureislessthanorequalto32degreesFahrenheit(thefreezingpointofwater).Ifitis,amessageisprinted.Otherwise,nomessageisprinted,andcodeexecutioncontinuesaftertheifstatement’sclosingbrace.

Theifstatementcanprovideanalternativesetofstatements,knownasanelseclause,forsituationswhentheifconditionisfalse.Thesestatementsareindicatedbytheelsekeyword.

1 temperatureInFahrenheit=40

Page 144: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 iftemperatureInFahrenheit<=32{

3 print("It'sverycold.Considerwearingascarf.")

4 }else{

5 print("It'snotthatcold.Wearat-shirt.")

6 }

7 //Prints"It'snotthatcold.Wearat-shirt."

Oneofthesetwobranchesisalwaysexecuted.Becausethetemperaturehasincreasedto40degreesFahrenheit,itisnolongercoldenoughtoadvisewearingascarfandsotheelsebranchistriggeredinstead.

Youcanchainmultipleifstatementstogethertoconsideradditionalclauses.

1 temperatureInFahrenheit=90

2 iftemperatureInFahrenheit<=32{

3 print("It'sverycold.Considerwearingascarf.")

4 }elseiftemperatureInFahrenheit>=86{

5 print("It'sreallywarm.Don'tforgettowearsunscreen.")

6 }else{

7 print("It'snotthatcold.Wearat-shirt.")

8 }

9 //Prints"It'sreallywarm.Don'tforgettowearsunscreen."

Here,anadditionalifstatementwasaddedtorespondtoparticularlywarmtemperatures.Thefinalelseclauseremains,anditprintsaresponseforanytemperaturesthatareneithertoowarmnortoocold.

Thefinalelseclauseisoptional,however,andcanbeexcludedifthesetofconditionsdoesnotneedtobecomplete.

1 temperatureInFahrenheit=72

2 iftemperatureInFahrenheit<=32{

3 print("It'sverycold.Considerwearingascarf.")

Page 145: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 }elseiftemperatureInFahrenheit>=86{

5 print("It'sreallywarm.Don'tforgettowearsunscreen.")

6 }

Becausethetemperatureisneithertoocoldnortoowarmtotriggertheiforelseifconditions,nomessageisprinted.

SwitchAswitchstatementconsidersavalueandcomparesitagainstseveralpossiblematchingpatterns.Itthenexecutesanappropriateblockofcode,basedonthefirstpatternthatmatchessuccessfully.Aswitchstatementprovidesanalternativetotheifstatementforrespondingtomultiplepotentialstates.

Initssimplestform,aswitchstatementcomparesavalueagainstoneormorevaluesofthesametype.

switch somevaluetoconsider {

case value1 :

respondtovalue1

case value2 ,

value3 :

respondtovalue2or3

default:

otherwise,dosomethingelse

}

Everyswitchstatementconsistsofmultiplepossiblecases,eachofwhichbeginswiththecasekeyword.Inadditiontocomparingagainstspecificvalues,Swiftprovidesseveralwaysforeachcasetospecifymorecomplexmatchingpatterns.Theseoptionsaredescribedlaterinthischapter.

Likethebodyofanifstatement,eachcaseisaseparatebranchofcodeexecution.Theswitchstatementdetermineswhichbranchshouldbeselected.

Page 146: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thisprocedureisknownasswitchingonthevaluethatisbeingconsidered.

Everyswitchstatementmustbeexhaustive.Thatis,everypossiblevalueofthetypebeingconsideredmustbematchedbyoneoftheswitchcases.Ifit’snotappropriatetoprovideacaseforeverypossiblevalue,youcandefineadefaultcasetocoveranyvaluesthatarenotaddressedexplicitly.Thisdefaultcaseisindicatedbythedefaultkeyword,andmustalwaysappearlast.

ThisexampleusesaswitchstatementtoconsiderasinglelowercasecharactercalledsomeCharacter:

1 letsomeCharacter:Character="z"

2 switchsomeCharacter{

3 case"a":

4 print("Thefirstletterofthealphabet")

5 case"z":

6 print("Thelastletterofthealphabet")

7 default:

8 print("Someothercharacter")

9 }

10 //Prints"Thelastletterofthealphabet"

Theswitchstatement’sfirstcasematchesthefirstletteroftheEnglishalphabet,a,anditssecondcasematchesthelastletter,z.Becausetheswitchmusthaveacaseforeverypossiblecharacter,notjusteveryalphabeticcharacter,thisswitchstatementusesadefaultcasetomatchallcharactersotherthanaandz.Thisprovisionensuresthattheswitchstatementisexhaustive.

NoImplicitFallthrough

IncontrastwithswitchstatementsinCandObjective-C,switchstatementsinSwiftdonotfallthroughthebottomofeachcaseandintothenextonebydefault.Instead,theentireswitchstatementfinishesitsexecutionassoonasthefirstmatchingswitchcaseiscompleted,withoutrequiringanexplicitbreakstatement.Thismakestheswitchstatementsaferandeasiertousethantheone

Page 147: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

inCandavoidsexecutingmorethanoneswitchcasebymistake.

NOTE

AlthoughbreakisnotrequiredinSwift,youcanuseabreakstatementtomatchandignoreaparticularcaseortobreakoutofamatchedcasebeforethatcasehascompleteditsexecution.Fordetails,seeBreakinaSwitchStatement.

Thebodyofeachcasemustcontainatleastoneexecutablestatement.Itisnotvalidtowritethefollowingcode,becausethefirstcaseisempty:

1 letanotherCharacter:Character="a"

2 switchanotherCharacter{

3 case"a"://Invalid,thecasehasanemptybody

4 case"A":

5 print("TheletterA")

6 default:

7 print("NottheletterA")

8 }

9 //Thiswillreportacompile-timeerror.

UnlikeaswitchstatementinC,thisswitchstatementdoesnotmatchboth"a"and"A".Rather,itreportsacompile-timeerrorthatcase"a":doesnotcontainanyexecutablestatements.Thisapproachavoidsaccidentalfallthroughfromonecasetoanotherandmakesforsafercodethatisclearerinitsintent.

Tomakeaswitchwithasinglecasethatmatchesboth"a"and"A",combinethetwovaluesintoacompoundcase,separatingthevalueswithcommas.

1 letanotherCharacter:Character="a"

2 switchanotherCharacter{

3 case"a","A":

4 print("TheletterA")

5 default:

Page 148: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 print("NottheletterA")

7 }

8 //Prints"TheletterA"

Forreadability,acompoundcasecanalsobewrittenovermultiplelines.Formoreinformationaboutcompoundcases,seeCompoundCases.

NOTE

Toexplicitlyfallthroughattheendofaparticularswitchcase,usethefallthroughkeyword,asdescribedinFallthrough.

IntervalMatching

Valuesinswitchcasescanbecheckedfortheirinclusioninaninterval.Thisexampleusesnumberintervalstoprovideanatural-languagecountfornumbersofanysize:

1 letapproximateCount=62

2 letcountedThings="moonsorbitingSaturn"

3 letnaturalCount:String

4 switchapproximateCount{

5 case0:

6 naturalCount="no"

7 case1..<5:

8 naturalCount="afew"

9 case5..<12:

10 naturalCount="several"

11 case12..<100:

12 naturalCount="dozensof"

13 case100..<1000:

14 naturalCount="hundredsof"

15 default:

Page 149: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

16 naturalCount="many"

17 }

18 print("Thereare\(naturalCount)\(countedThings).")

19 //Prints"TherearedozensofmoonsorbitingSaturn."

Intheaboveexample,approximateCountisevaluatedinaswitchstatement.Eachcasecomparesthatvaluetoanumberorinterval.BecausethevalueofapproximateCountfallsbetween12and100,naturalCountisassignedthevalue"dozensof",andexecutionistransferredoutoftheswitchstatement.

Tuples

Youcanusetuplestotestmultiplevaluesinthesameswitchstatement.Eachelementofthetuplecanbetestedagainstadifferentvalueorintervalofvalues.Alternatively,usetheunderscorecharacter(_),alsoknownasthewildcardpattern,tomatchanypossiblevalue.

Theexamplebelowtakesan(x,y)point,expressedasasimpletupleoftype(Int,Int),andcategorizesitonthegraphthatfollowstheexample.

1 letsomePoint=(1,1)

2 switchsomePoint{

3 case(0,0):

4 print("\(somePoint)isattheorigin")

5 case(_,0):

6 print("\(somePoint)isonthex-axis")

7 case(0,_):

8 print("\(somePoint)isonthey-axis")

9 case(-2...2,-2...2):

10 print("\(somePoint)isinsidethebox")

11 default:

12 print("\(somePoint)isoutsideofthebox")

13 }

Page 150: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

14 //Prints"(1,1)isinsidethebox"

Theswitchstatementdetermineswhetherthepointisattheorigin(0,0),ontheredx-axis,ontheorangey-axis,insidetheblue4-by-4boxcenteredontheorigin,oroutsideofthebox.

UnlikeC,Swiftallowsmultipleswitchcasestoconsiderthesamevalueorvalues.Infact,thepoint(0,0)couldmatchallfourofthecasesinthisexample.However,ifmultiplematchesarepossible,thefirstmatchingcaseisalwaysused.Thepoint(0,0)wouldmatchcase(0,0)first,andsoallothermatchingcaseswouldbeignored.

ValueBindings

Aswitchcasecannamethevalueorvaluesitmatchestotemporaryconstantsorvariables,foruseinthebodyofthecase.Thisbehaviorisknownasvaluebinding,becausethevaluesareboundtotemporaryconstantsorvariableswithinthecase’sbody.

Theexamplebelowtakesan(x,y)point,expressedasatupleoftype(Int,Int),andcategorizesitonthegraphthatfollows:

1 letanotherPoint=(2,0)

2 switchanotherPoint{

Page 151: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 case(letx,0):

4 print("onthex-axiswithanxvalueof\(x)")

5 case(0,lety):

6 print("onthey-axiswithayvalueof\(y)")

7 caselet(x,y):

8 print("somewhereelseat(\(x),\(y))")

9 }

10 //Prints"onthex-axiswithanxvalueof2"

Theswitchstatementdetermineswhetherthepointisontheredx-axis,ontheorangey-axis,orelsewhere(onneitheraxis).

Thethreeswitchcasesdeclareplaceholderconstantsxandy,whichtemporarilytakeononeorbothtuplevaluesfromanotherPoint.Thefirstcase,case(letx,0),matchesanypointwithayvalueof0andassignsthepoint’sxvaluetothetemporaryconstantx.Similarly,thesecondcase,case(0,lety),matchesanypointwithanxvalueof0andassignsthepoint’syvaluetothetemporaryconstanty.

Afterthetemporaryconstantsaredeclared,theycanbeusedwithinthecase’scodeblock.Here,theyareusedtoprintthecategorizationofthepoint.

Thisswitchstatementdoesnothaveadefaultcase.Thefinalcase,caselet

Page 152: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

(x,y),declaresatupleoftwoplaceholderconstantsthatcanmatchanyvalue.BecauseanotherPointisalwaysatupleoftwovalues,thiscasematchesallpossibleremainingvalues,andadefaultcaseisnotneededtomaketheswitchstatementexhaustive.

Where

Aswitchcasecanuseawhereclausetocheckforadditionalconditions.

Theexamplebelowcategorizesan(x,y)pointonthefollowinggraph:

1 letyetAnotherPoint=(1,-1)

2 switchyetAnotherPoint{

3 caselet(x,y)wherex==y:

4 print("(\(x),\(y))isonthelinex==y")

5 caselet(x,y)wherex==-y:

6 print("(\(x),\(y))isonthelinex==-y")

7 caselet(x,y):

8 print("(\(x),\(y))isjustsomearbitrarypoint")

9 }

10 //Prints"(1,-1)isonthelinex==-y"

Page 153: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theswitchstatementdetermineswhetherthepointisonthegreendiagonallinewherex==y,onthepurplediagonallinewherex==-y,orneither.

Thethreeswitchcasesdeclareplaceholderconstantsxandy,whichtemporarilytakeonthetwotuplevaluesfromyetAnotherPoint.Theseconstantsareusedaspartofawhereclause,tocreateadynamicfilter.Theswitchcasematchesthecurrentvalueofpointonlyifthewhereclause’sconditionevaluatestotrueforthatvalue.

Asinthepreviousexample,thefinalcasematchesallpossibleremainingvalues,andsoadefaultcaseisnotneededtomaketheswitchstatementexhaustive.

CompoundCases

Multipleswitchcasesthatsharethesamebodycanbecombinedbywritingseveralpatternsaftercase,withacommabetweeneachofthepatterns.Ifanyofthepatternsmatch,thenthecaseisconsideredtomatch.Thepatternscanbewrittenovermultiplelinesifthelistislong.Forexample:

1 letsomeCharacter:Character="e"

2 switchsomeCharacter{

3 case"a","e","i","o","u":

4 print("\(someCharacter)isavowel")

5 case"b","c","d","f","g","h","j","k","l","m",

6 "n","p","q","r","s","t","v","w","x","y","z":

7 print("\(someCharacter)isaconsonant")

8 default:

9 print("\(someCharacter)isnotavoweloraconsonant")

10 }

11 //Prints"eisavowel"

Theswitchstatement’sfirstcasematchesallfivelowercasevowelsintheEnglishlanguage.Similarly,itssecondcasematchesalllowercaseEnglishconsonants.Finally,thedefaultcasematchesanyothercharacter.

Page 154: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Compoundcasescanalsoincludevaluebindings.Allofthepatternsofacompoundcasehavetoincludethesamesetofvaluebindings,andeachbindinghastogetavalueofthesametypefromallofthepatternsinthecompoundcase.Thisensuresthat,nomatterwhichpartofthecompoundcasematched,thecodeinthebodyofthecasecanalwaysaccessavalueforthebindingsandthatthevaluealwayshasthesametype.

1 letstillAnotherPoint=(9,0)

2 switchstillAnotherPoint{

3 case(letdistance,0),(0,letdistance):

4 print("Onanaxis,\(distance)fromtheorigin")

5 default:

6 print("Notonanaxis")

7 }

8 //Prints"Onanaxis,9fromtheorigin"

Thecaseabovehastwopatterns:(letdistance,0)matchespointsonthex-axisand(0,letdistance)matchespointsonthey-axis.Bothpatternsincludeabindingfordistanceanddistanceisanintegerinbothpatterns—whichmeansthatthecodeinthebodyofthecasecanalwaysaccessavaluefordistance.

ControlTransferStatements

Controltransferstatementschangetheorderinwhichyourcodeisexecuted,bytransferringcontrolfromonepieceofcodetoanother.Swifthasfivecontroltransferstatements:

continue

break

fallthrough

Page 155: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

return

throw

Thecontinue,break,andfallthroughstatementsaredescribedbelow.ThereturnstatementisdescribedinFunctions,andthethrowstatementisdescribedinPropagatingErrorsUsingThrowingFunctions.

ContinueThecontinuestatementtellsalooptostopwhatitisdoingandstartagainatthebeginningofthenextiterationthroughtheloop.Itsays“Iamdonewiththecurrentloopiteration”withoutleavingtheloopaltogether.

Thefollowingexampleremovesallvowelsandspacesfromalowercasestringtocreateacrypticpuzzlephrase:

1 letpuzzleInput="greatmindsthinkalike"

2 varpuzzleOutput=""

3 letcharactersToRemove:[Character]=["a","e","i","o","u",

""]

4 forcharacterinpuzzleInput{

5 ifcharactersToRemove.contains(character){

6 continue

7 }

8 puzzleOutput.append(character)

9 }

10 print(puzzleOutput)

11 //Prints"grtmndsthnklk"

Thecodeabovecallsthecontinuekeywordwheneveritmatchesavoweloraspace,causingthecurrentiterationofthelooptoendimmediatelyandtojumpstraighttothestartofthenextiteration.

Page 156: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

BreakThebreakstatementendsexecutionofanentirecontrolflowstatementimmediately.Thebreakstatementcanbeusedinsideaswitchorloopstatementwhenyouwanttoterminatetheexecutionoftheswitchorloopstatementearlierthanwouldotherwisebethecase.

BreakinaLoopStatement

Whenusedinsidealoopstatement,breakendstheloop’sexecutionimmediatelyandtransferscontroltothecodeaftertheloop’sclosingbrace(}).Nofurthercodefromthecurrentiterationoftheloopisexecuted,andnofurtheriterationsofthelooparestarted.

BreakinaSwitchStatement

Whenusedinsideaswitchstatement,breakcausestheswitchstatementtoenditsexecutionimmediatelyandtotransfercontroltothecodeaftertheswitchstatement’sclosingbrace(}).

Thisbehaviorcanbeusedtomatchandignoreoneormorecasesinaswitchstatement.BecauseSwift’sswitchstatementisexhaustiveanddoesnotallowemptycases,itissometimesnecessarytodeliberatelymatchandignoreacaseinordertomakeyourintentionsexplicit.Youdothisbywritingthebreakstatementastheentirebodyofthecaseyouwanttoignore.Whenthatcaseismatchedbytheswitchstatement,thebreakstatementinsidethecaseendstheswitchstatement’sexecutionimmediately.

NOTE

Aswitchcasethatcontainsonlyacommentisreportedasacompile-timeerror.Commentsarenotstatementsanddonotcauseaswitchcasetobeignored.Alwaysuseabreakstatementtoignoreaswitchcase.

ThefollowingexampleswitchesonaCharactervalueanddetermineswhetheritrepresentsanumbersymbolinoneoffourlanguages.Forbrevity,multiplevaluesarecoveredinasingleswitchcase.

Page 157: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letnumberSymbol:Character="" //Chinesesymbolforthe

number3

2 varpossibleIntegerValue:Int?

3 switchnumberSymbol{

4 case"1","١","" ,"�":

5 possibleIntegerValue=1

6 case"2","٢","" ,"�":

7 possibleIntegerValue=2

8 case"3","٣","" ,"�":

9 possibleIntegerValue=3

10 case"4","٤","" ,"�":

11 possibleIntegerValue=4

12 default:

13 break

14 }

15 ifletintegerValue=possibleIntegerValue{

16 print("Theintegervalueof\(numberSymbol)is\

(integerValue).")

17 }else{

18 print("Anintegervaluecouldnotbefoundfor\

(numberSymbol).")

19 }

20 //Prints"Theintegervalueofis3."

ThisexamplechecksnumberSymboltodeterminewhetheritisaLatin,Arabic,Chinese,orThaisymbolforthenumbers1to4.Ifamatchisfound,oneoftheswitchstatement’scasessetsanoptionalInt?variablecalledpossibleIntegerValuetoanappropriateintegervalue.

Aftertheswitchstatementcompletesitsexecution,theexampleusesoptionalbindingtodeterminewhetheravaluewasfound.ThepossibleIntegerValue

Page 158: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

variablehasanimplicitinitialvalueofnilbyvirtueofbeinganoptionaltype,andsotheoptionalbindingwillsucceedonlyifpossibleIntegerValuewassettoanactualvaluebyoneoftheswitchstatement’sfirstfourcases.

Becauseit’snotpracticaltolisteverypossibleCharactervalueintheexampleabove,adefaultcasehandlesanycharactersthatarenotmatched.Thisdefaultcasedoesnotneedtoperformanyaction,andsoitiswrittenwithasinglebreakstatementasitsbody.Assoonasthedefaultcaseismatched,thebreakstatementendstheswitchstatement’sexecution,andcodeexecutioncontinuesfromtheifletstatement.

FallthroughInSwift,switchstatementsdon’tfallthroughthebottomofeachcaseandintothenextone.Thatis,theentireswitchstatementcompletesitsexecutionassoonasthefirstmatchingcaseiscompleted.Bycontrast,Crequiresyoutoinsertanexplicitbreakstatementattheendofeveryswitchcasetopreventfallthrough.AvoidingdefaultfallthroughmeansthatSwiftswitchstatementsaremuchmoreconciseandpredictablethantheircounterpartsinC,andthustheyavoidexecutingmultipleswitchcasesbymistake.

IfyouneedC-stylefallthroughbehavior,youcanoptintothisbehavioronacase-by-casebasiswiththefallthroughkeyword.Theexamplebelowusesfallthroughtocreateatextualdescriptionofanumber.

1 letintegerToDescribe=5

2 vardescription="Thenumber\(integerToDescribe)is"

3 switchintegerToDescribe{

4 case2,3,5,7,11,13,17,19:

5 description+="aprimenumber,andalso"

6 fallthrough

7 default:

8 description+="aninteger."

9 }

Page 159: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

10 print(description)

11 //Prints"Thenumber5isaprimenumber,andalsoan

integer."

ThisexampledeclaresanewStringvariablecalleddescriptionandassignsitaninitialvalue.ThefunctionthenconsidersthevalueofintegerToDescribeusingaswitchstatement.IfthevalueofintegerToDescribeisoneoftheprimenumbersinthelist,thefunctionappendstexttotheendofdescription,tonotethatthenumberisprime.Itthenusesthefallthroughkeywordto“fallinto”thedefaultcaseaswell.Thedefaultcaseaddssomeextratexttotheendofthedescription,andtheswitchstatementiscomplete.

UnlessthevalueofintegerToDescribeisinthelistofknownprimenumbers,itisnotmatchedbythefirstswitchcaseatall.Becausetherearenootherspecificcases,integerToDescribeismatchedbythedefaultcase.

Aftertheswitchstatementhasfinishedexecuting,thenumber’sdescriptionisprintedusingtheprint(_:separator:terminator:)function.Inthisexample,thenumber5iscorrectlyidentifiedasaprimenumber.

NOTE

Thefallthroughkeyworddoesnotcheckthecaseconditionsfortheswitchcasethatitcausesexecutiontofallinto.Thefallthroughkeywordsimplycausescodeexecutiontomovedirectlytothestatementsinsidethenextcase(ordefaultcase)block,asinC’sstandardswitchstatementbehavior.

LabeledStatementsInSwift,youcannestloopsandconditionalstatementsinsideotherloopsandconditionalstatementstocreatecomplexcontrolflowstructures.However,loopsandconditionalstatementscanbothusethebreakstatementtoendtheirexecutionprematurely.Therefore,itissometimesusefultobeexplicitaboutwhichlooporconditionalstatementyouwantabreakstatementtoterminate.Similarly,ifyouhavemultiplenestedloops,itcanbeusefultobeexplicitaboutwhichloopthecontinuestatementshouldaffect.

Page 160: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Toachievetheseaims,youcanmarkaloopstatementorconditionalstatementwithastatementlabel.Withaconditionalstatement,youcanuseastatementlabelwiththebreakstatementtoendtheexecutionofthelabeledstatement.Withaloopstatement,youcanuseastatementlabelwiththebreakorcontinuestatementtoendorcontinuetheexecutionofthelabeledstatement.

Alabeledstatementisindicatedbyplacingalabelonthesamelineasthestatement’sintroducerkeyword,followedbyacolon.Here’sanexampleofthissyntaxforawhileloop,althoughtheprincipleisthesameforallloopsandswitchstatements:

labelname :while condition {

statements

}

ThefollowingexampleusesthebreakandcontinuestatementswithalabeledwhileloopforanadaptedversionoftheSnakesandLaddersgamethatyousawearlierinthischapter.Thistimearound,thegamehasanextrarule:

Towin,youmustlandexactlyonsquare25.

Ifaparticulardicerollwouldtakeyoubeyondsquare25,youmustrollagainuntilyourolltheexactnumberneededtolandonsquare25.

Thegameboardisthesameasbefore.

Page 161: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThevaluesoffinalSquare,board,square,anddiceRollareinitializedinthesamewayasbefore:

1 letfinalSquare=25

2 varboard=[Int](repeating:0,count:finalSquare+1)

3 board[03]=+08;board[06]=+11;board[09]=+09;board[10]=

+02

4 board[14]=-10;board[19]=-11;board[22]=-02;board[24]=

-08

5 varsquare=0

6 vardiceRoll=0

Thisversionofthegameusesawhileloopandaswitchstatementtoimplementthegame’slogic.ThewhileloophasastatementlabelcalledgameLooptoindicatethatitisthemaingameloopfortheSnakesandLaddersgame.

Thewhileloop’sconditioniswhilesquare!=finalSquare,toreflectthatyoumustlandexactlyonsquare25.

1 gameLoop:whilesquare!=finalSquare{

2 diceRoll+=1

Page 162: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 ifdiceRoll==7{diceRoll=1}

4 switchsquare+diceRoll{

5 casefinalSquare:

6 //diceRollwillmoveustothefinalsquare,sothe

gameisover

7 breakgameLoop

8 caseletnewSquarewherenewSquare>finalSquare:

9 //diceRollwillmoveusbeyondthefinalsquare,so

rollagain

10 continuegameLoop

11 default:

12 //thisisavalidmove,sofindoutitseffect

13 square+=diceRoll

14 square+=board[square]

15 }

16 }

17 print("Gameover!")

Thediceisrolledatthestartofeachloop.Ratherthanmovingtheplayerimmediately,theloopusesaswitchstatementtoconsidertheresultofthemoveandtodeterminewhetherthemoveisallowed:

Ifthedicerollwillmovetheplayerontothefinalsquare,thegameisover.ThebreakgameLoopstatementtransferscontroltothefirstlineofcodeoutsideofthewhileloop,whichendsthegame.

Ifthedicerollwillmovetheplayerbeyondthefinalsquare,themoveisinvalidandtheplayerneedstorollagain.ThecontinuegameLoopstatementendsthecurrentwhileloopiterationandbeginsthenextiterationoftheloop.

Inallothercases,thedicerollisavalidmove.TheplayermovesforwardbydiceRollsquares,andthegamelogicchecksforanysnakesandladders.

Page 163: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theloopthenends,andcontrolreturnstothewhileconditiontodecidewhetheranotherturnisrequired.

NOTE

IfthebreakstatementabovedidnotusethegameLooplabel,itwouldbreakoutoftheswitchstatement,notthewhilestatement.UsingthegameLooplabelmakesitclearwhichcontrolstatementshouldbeterminated.

ItisnotstrictlynecessarytousethegameLooplabelwhencallingcontinuegameLooptojumptothenextiterationoftheloop.Thereisonlyoneloopinthegame,andthereforenoambiguityastowhichloopthecontinuestatementwillaffect.However,thereisnoharminusingthegameLooplabelwiththecontinuestatement.Doingsoisconsistentwiththelabel’susealongsidethebreakstatementandhelpsmakethegame’slogicclearertoreadandunderstand.

EarlyExit

Aguardstatement,likeanifstatement,executesstatementsdependingontheBooleanvalueofanexpression.Youuseaguardstatementtorequirethataconditionmustbetrueinorderforthecodeaftertheguardstatementtobeexecuted.Unlikeanifstatement,aguardstatementalwayshasanelseclause—thecodeinsidetheelseclauseisexecutediftheconditionisnottrue.

1 funcgreet(person:[String:String]){

2 guardletname=person["name"]else{

3 return

4 }

5

6 print("Hello\(name)!")

7

8 guardletlocation=person["location"]else{

9 print("Ihopetheweatherisnicenearyou.")

10 return

11 }

Page 164: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

12

13 print("Ihopetheweatherisnicein\(location).")

14 }

15

16 greet(person:["name":"John"])

17 //Prints"HelloJohn!"

18 //Prints"Ihopetheweatherisnicenearyou."

19 greet(person:["name":"Jane","location":"Cupertino"])

20 //Prints"HelloJane!"

21 //Prints"IhopetheweatherisniceinCupertino."

Iftheguardstatement’sconditionismet,codeexecutioncontinuesaftertheguardstatement’sclosingbrace.Anyvariablesorconstantsthatwereassignedvaluesusinganoptionalbindingaspartoftheconditionareavailablefortherestofthecodeblockthattheguardstatementappearsin.

Ifthatconditionisnotmet,thecodeinsidetheelsebranchisexecuted.Thatbranchmusttransfercontroltoexitthecodeblockinwhichtheguardstatementappears.Itcandothiswithacontroltransferstatementsuchasreturn,break,continue,orthrow,oritcancallafunctionormethodthatdoesn’treturn,suchasfatalError(_:file:line:).

Usingaguardstatementforrequirementsimprovesthereadabilityofyourcode,comparedtodoingthesamecheckwithanifstatement.Itletsyouwritethecodethat’stypicallyexecutedwithoutwrappingitinanelseblock,anditletsyoukeepthecodethathandlesaviolatedrequirementnexttotherequirement.

CheckingAPIAvailability

Swifthasbuilt-insupportforcheckingAPIavailability,whichensuresthatyoudon’taccidentallyuseAPIsthatareunavailableonagivendeploymenttarget.

ThecompilerusesavailabilityinformationintheSDKtoverifythatallofthe

Page 165: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

APIsusedinyourcodeareavailableonthedeploymenttargetspecifiedbyyourproject.SwiftreportsanerroratcompiletimeifyoutrytouseanAPIthatisn’tavailable.

Youuseanavailabilityconditioninaniforguardstatementtoconditionallyexecuteablockofcode,dependingonwhethertheAPIsyouwanttouseareavailableatruntime.ThecompilerusestheinformationfromtheavailabilityconditionwhenitverifiesthattheAPIsinthatblockofcodeareavailable.

1 if#available(iOS10,macOS10.12,*){

2 //UseiOS10APIsoniOS,andusemacOS10.12APIson

macOS

3 }else{

4 //FallbacktoearlieriOSandmacOSAPIs

5 }

TheavailabilityconditionabovespecifiesthatiniOS,thebodyoftheifstatementexecutesonlyiniOS10andlater;inmacOS,onlyinmacOS10.12andlater.Thelastargument,*,isrequiredandspecifiesthatonanyotherplatform,thebodyoftheifexecutesontheminimumdeploymenttargetspecifiedbyyourtarget.

Initsgeneralform,theavailabilityconditiontakesalistofplatformnamesandversions.YouuseplatformnamessuchasiOS,macOS,watchOS,andtvOS—forthefulllist,seeDeclarationAttributes.InadditiontospecifyingmajorversionnumberslikeiOS8ormacOS10.10,youcanspecifyminorversionsnumberslikeiOS11.2.6andmacOS10.13.3.

if#available( platformname version , ... ,*){

statementstoexecuteiftheAPIsareavailable

}else{

fallbackstatementstoexecuteiftheAPIsareunavailable

}

Page 166: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Functions

Functionsareself-containedchunksofcodethatperformaspecifictask.Yougiveafunctionanamethatidentifieswhatitdoes,andthisnameisusedto“call”thefunctiontoperformitstaskwhenneeded.

Swift’sunifiedfunctionsyntaxisflexibleenoughtoexpressanythingfromasimpleC-stylefunctionwithnoparameternamestoacomplexObjective-C-stylemethodwithnamesandargumentlabelsforeachparameter.Parameterscanprovidedefaultvaluestosimplifyfunctioncallsandcanbepassedasin-outparameters,whichmodifyapassedvariableoncethefunctionhascompleteditsexecution.

EveryfunctioninSwifthasatype,consistingofthefunction’sparametertypesandreturntype.YoucanusethistypelikeanyothertypeinSwift,whichmakesiteasytopassfunctionsasparameterstootherfunctions,andtoreturnfunctionsfromfunctions.Functionscanalsobewrittenwithinotherfunctionstoencapsulateusefulfunctionalitywithinanestedfunctionscope.

DefiningandCallingFunctions

Whenyoudefineafunction,youcanoptionallydefineoneormorenamed,typedvaluesthatthefunctiontakesasinput,knownasparameters.Youcanalsooptionallydefineatypeofvaluethatthefunctionwillpassbackasoutputwhenitisdone,knownasitsreturntype.

Everyfunctionhasafunctionname,whichdescribesthetaskthatthefunctionperforms.Touseafunction,you“call”thatfunctionwithitsnameandpassitinputvalues(knownasarguments)thatmatchthetypesofthefunction’sparameters.Afunction’sargumentsmustalwaysbeprovidedinthesameorderasthefunction’sparameterlist.

Thefunctionintheexamplebelowiscalledgreet(person:),becausethat’swhatitdoes—ittakesaperson’snameasinputandreturnsagreetingforthatperson.

Page 167: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Toaccomplishthis,youdefineoneinputparameter—aStringvaluecalledperson—andareturntypeofString,whichwillcontainagreetingforthatperson:

1 funcgreet(person:String)->String{

2 letgreeting="Hello,"+person+"!"

3 returngreeting

4 }

Allofthisinformationisrolledupintothefunction’sdefinition,whichisprefixedwiththefunckeyword.Youindicatethefunction’sreturntypewiththereturnarrow->(ahyphenfollowedbyarightanglebracket),whichisfollowedbythenameofthetypetoreturn.

Thedefinitiondescribeswhatthefunctiondoes,whatitexpectstoreceive,andwhatitreturnswhenitisdone.Thedefinitionmakesiteasyforthefunctiontobecalledunambiguouslyfromelsewhereinyourcode:

1 print(greet(person:"Anna"))

2 //Prints"Hello,Anna!"

3 print(greet(person:"Brian"))

4 //Prints"Hello,Brian!"

Youcallthegreet(person:)functionbypassingitaStringvalueafterthepersonargumentlabel,suchasgreet(person:"Anna").BecausethefunctionreturnsaStringvalue,greet(person:)canbewrappedinacalltotheprint(_:separator:terminator:)functiontoprintthatstringandseeitsreturnvalue,asshownabove.

NOTE

Theprint(_:separator:terminator:)functiondoesn’thavealabelforitsfirstargument,anditsotherargumentsareoptionalbecausetheyhaveadefaultvalue.ThesevariationsonfunctionsyntaxarediscussedbelowinFunctionArgumentLabelsandParameterNamesandDefaultParameterValues.

Page 168: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thebodyofthegreet(person:)functionstartsbydefininganewStringconstantcalledgreetingandsettingittoasimplegreetingmessage.Thisgreetingisthenpassedbackoutofthefunctionusingthereturnkeyword.Inthelineofcodethatsaysreturngreeting,thefunctionfinishesitsexecutionandreturnsthecurrentvalueofgreeting.

Youcancallthegreet(person:)functionmultipletimeswithdifferentinputvalues.Theexampleaboveshowswhathappensifitiscalledwithaninputvalueof"Anna",andaninputvalueof"Brian".Thefunctionreturnsatailoredgreetingineachcase.

Tomakethebodyofthisfunctionshorter,youcancombinethemessagecreationandthereturnstatementintooneline:

1 funcgreetAgain(person:String)->String{

2 return"Helloagain,"+person+"!"

3 }

4 print(greetAgain(person:"Anna"))

5 //Prints"Helloagain,Anna!"

FunctionParametersandReturnValues

FunctionparametersandreturnvaluesareextremelyflexibleinSwift.Youcandefineanythingfromasimpleutilityfunctionwithasingleunnamedparametertoacomplexfunctionwithexpressiveparameternamesanddifferentparameteroptions.

FunctionsWithoutParametersFunctionsarenotrequiredtodefineinputparameters.Here’safunctionwithnoinputparameters,whichalwaysreturnsthesameStringmessagewheneveritiscalled:

Page 169: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 funcsayHelloWorld()->String{

2 return"hello,world"

3 }

4 print(sayHelloWorld())

5 //Prints"hello,world"

Thefunctiondefinitionstillneedsparenthesesafterthefunction’sname,eventhoughitdoesnottakeanyparameters.Thefunctionnameisalsofollowedbyanemptypairofparentheseswhenthefunctioniscalled.

FunctionsWithMultipleParametersFunctionscanhavemultipleinputparameters,whicharewrittenwithinthefunction’sparentheses,separatedbycommas.

Thisfunctiontakesaperson’snameandwhethertheyhavealreadybeengreetedasinput,andreturnsanappropriategreetingforthatperson:

1 funcgreet(person:String,alreadyGreeted:Bool)->String{

2 ifalreadyGreeted{

3 returngreetAgain(person:person)

4 }else{

5 returngreet(person:person)

6 }

7 }

8 print(greet(person:"Tim",alreadyGreeted:true))

9 //Prints"Helloagain,Tim!"

Youcallthegreet(person:alreadyGreeted:)functionbypassingitbothaStringargumentvaluelabeledpersonandaBoolargumentvaluelabeledalreadyGreetedinparentheses,separatedbycommas.Notethatthisfunctionisdistinctfromthegreet(person:)functionshowninanearliersection.Althoughbothfunctionshavenamesthatbeginwithgreet,the

Page 170: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

greet(person:alreadyGreeted:)functiontakestwoargumentsbutthegreet(person:)functiontakesonlyone.

FunctionsWithoutReturnValuesFunctionsarenotrequiredtodefineareturntype.Here’saversionofthegreet(person:)function,whichprintsitsownStringvalueratherthanreturningit:

1 funcgreet(person:String){

2 print("Hello,\(person)!")

3 }

4 greet(person:"Dave")

5 //Prints"Hello,Dave!"

Becauseitdoesnotneedtoreturnavalue,thefunction’sdefinitiondoesnotincludethereturnarrow(->)orareturntype.

NOTE

Strictlyspeaking,thisversionofthegreet(person:)functiondoesstillreturnavalue,eventhoughnoreturnvalueisdefined.FunctionswithoutadefinedreturntypereturnaspecialvalueoftypeVoid.Thisissimplyanemptytuple,whichiswrittenas().

Thereturnvalueofafunctioncanbeignoredwhenitiscalled:

1 funcprintAndCount(string:String)->Int{

2 print(string)

3 returnstring.count

4 }

5 funcprintWithoutCounting(string:String){

6 let_=printAndCount(string:string)

7 }

8 printAndCount(string:"hello,world")

Page 171: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 //prints"hello,world"andreturnsavalueof12

10 printWithoutCounting(string:"hello,world")

11 //prints"hello,world"butdoesnotreturnavalue

Thefirstfunction,printAndCount(string:),printsastring,andthenreturnsitscharactercountasanInt.Thesecondfunction,printWithoutCounting(string:),callsthefirstfunction,butignoresitsreturnvalue.Whenthesecondfunctioniscalled,themessageisstillprintedbythefirstfunction,butthereturnedvalueisnotused.

NOTE

Returnvaluescanbeignored,butafunctionthatsaysitwillreturnavaluemustalwaysdoso.Afunctionwithadefinedreturntypecannotallowcontroltofalloutofthebottomofthefunctionwithoutreturningavalue,andattemptingtodosowillresultinacompile-timeerror.

FunctionswithMultipleReturnValuesYoucanuseatupletypeasthereturntypeforafunctiontoreturnmultiplevaluesaspartofonecompoundreturnvalue.

TheexamplebelowdefinesafunctioncalledminMax(array:),whichfindsthesmallestandlargestnumbersinanarrayofIntvalues:

1 funcminMax(array:[Int])->(min:Int,max:Int){

2 varcurrentMin=array[0]

3 varcurrentMax=array[0]

4 forvalueinarray[1..<array.count]{

5 ifvalue<currentMin{

6 currentMin=value

7 }elseifvalue>currentMax{

8 currentMax=value

9 }

10 }

Page 172: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

11 return(currentMin,currentMax)

12 }

TheminMax(array:)functionreturnsatuplecontainingtwoIntvalues.Thesevaluesarelabeledminandmaxsothattheycanbeaccessedbynamewhenqueryingthefunction’sreturnvalue.

ThebodyoftheminMax(array:)functionstartsbysettingtwoworkingvariablescalledcurrentMinandcurrentMaxtothevalueofthefirstintegerinthearray.ThefunctiontheniteratesovertheremainingvaluesinthearrayandcheckseachvaluetoseeifitissmallerorlargerthanthevaluesofcurrentMinandcurrentMaxrespectively.Finally,theoverallminimumandmaximumvaluesarereturnedasatupleoftwoIntvalues.

Becausethetuple’smembervaluesarenamedaspartofthefunction’sreturntype,theycanbeaccessedwithdotsyntaxtoretrievetheminimumandmaximumfoundvalues:

1 letbounds=minMax(array:[8,-6,2,109,3,71])

2 print("minis\(bounds.min)andmaxis\(bounds.max)")

3 //Prints"minis-6andmaxis109"

Notethatthetuple’smembersdonotneedtobenamedatthepointthatthetupleisreturnedfromthefunction,becausetheirnamesarealreadyspecifiedaspartofthefunction’sreturntype.

OptionalTupleReturnTypes

Ifthetupletypetobereturnedfromafunctionhasthepotentialtohave“novalue”fortheentiretuple,youcanuseanoptionaltuplereturntypetoreflectthefactthattheentiretuplecanbenil.Youwriteanoptionaltuplereturntypebyplacingaquestionmarkafterthetupletype’sclosingparenthesis,suchas(Int,Int)?or(String,Int,Bool)?.

NOTE

Anoptionaltupletypesuchas(Int,Int)?isdifferentfromatuplethatcontainsoptionaltypes

Page 173: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

suchas(Int?,Int?).Withanoptionaltupletype,theentiretupleisoptional,notjusteachindividualvaluewithinthetuple.

TheminMax(array:)functionabovereturnsatuplecontainingtwoIntvalues.However,thefunctiondoesnotperformanysafetychecksonthearrayitispassed.Ifthearrayargumentcontainsanemptyarray,theminMax(array:)function,asdefinedabove,willtriggeraruntimeerrorwhenattemptingtoaccessarray[0].

Tohandleanemptyarraysafely,writetheminMax(array:)functionwithanoptionaltuplereturntypeandreturnavalueofnilwhenthearrayisempty:

1 funcminMax(array:[Int])->(min:Int,max:Int)?{

2 ifarray.isEmpty{returnnil}

3 varcurrentMin=array[0]

4 varcurrentMax=array[0]

5 forvalueinarray[1..<array.count]{

6 ifvalue<currentMin{

7 currentMin=value

8 }elseifvalue>currentMax{

9 currentMax=value

10 }

11 }

12 return(currentMin,currentMax)

13 }

YoucanuseoptionalbindingtocheckwhetherthisversionoftheminMax(array:)functionreturnsanactualtuplevalueornil:

1 ifletbounds=minMax(array:[8,-6,2,109,3,71]){

2 print("minis\(bounds.min)andmaxis\(bounds.max)")

3 }

4 //Prints"minis-6andmaxis109"

Page 174: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

FunctionsWithanImplicitReturnIftheentirebodyofthefunctionisasingleexpression,thefunctionimplicitlyreturnsthatexpression.Forexample,bothfunctionsbelowhavethesamebehavior:

1 funcgreeting(forperson:String)->String{

2 "Hello,"+person+"!"

3 }

4 print(greeting(for:"Dave"))

5 //Prints"Hello,Dave!"

6

7 funcanotherGreeting(forperson:String)->String{

8 return"Hello,"+person+"!"

9 }

10 print(anotherGreeting(for:"Dave"))

11 //Prints"Hello,Dave!"

Theentiredefinitionofthegreeting(for:)functionisthegreetingmessagethatitreturns,whichmeansitcanusethisshorterform.TheanotherGreeting(for:)functionreturnsthesamegreetingmessage,usingthereturnkeywordlikealongerfunction.Anyfunctionthatyouwriteasjustonereturnlinecanomitthereturn.

Asyou’llseeinShorthandGetterDeclaration,propertygetterscanalsouseanimplicitreturn.

FunctionArgumentLabelsandParameterNames

Eachfunctionparameterhasbothanargumentlabelandaparametername.Theargumentlabelisusedwhencallingthefunction;eachargumentiswritteninthefunctioncallwithitsargumentlabelbeforeit.Theparameternameisusedintheimplementationofthefunction.Bydefault,parametersusetheirparametername

Page 175: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

astheirargumentlabel.

1 funcsomeFunction(firstParameterName:Int,secondParameterName:

Int){

2 //Inthefunctionbody,firstParameterNameand

secondParameterName

3 //refertotheargumentvaluesforthefirstandsecond

parameters.

4 }

5 someFunction(firstParameterName:1,secondParameterName:2)

Allparametersmusthaveuniquenames.Althoughit’spossibleformultipleparameterstohavethesameargumentlabel,uniqueargumentlabelshelpmakeyourcodemorereadable.

SpecifyingArgumentLabelsYouwriteanargumentlabelbeforetheparametername,separatedbyaspace:

1 funcsomeFunction(argumentLabelparameterName:Int){

2 //Inthefunctionbody,parameterNamereferstothe

argumentvalue

3 //forthatparameter.

4 }

Here’savariationofthegreet(person:)functionthattakesaperson’snameandhometownandreturnsagreeting:

1 funcgreet(person:String,fromhometown:String)->String{

2 return"Hello\(person)!Gladyoucouldvisitfrom\

(hometown)."

3 }

Page 176: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 print(greet(person:"Bill",from:"Cupertino"))

5 //Prints"HelloBill!GladyoucouldvisitfromCupertino."

Theuseofargumentlabelscanallowafunctiontobecalledinanexpressive,sentence-likemanner,whilestillprovidingafunctionbodythatisreadableandclearinintent.

OmittingArgumentLabelsIfyoudon’twantanargumentlabelforaparameter,writeanunderscore(_)insteadofanexplicitargumentlabelforthatparameter.

1 funcsomeFunction(_firstParameterName:Int,

secondParameterName:Int){

2 //Inthefunctionbody,firstParameterNameand

secondParameterName

3 //refertotheargumentvaluesforthefirstandsecond

parameters.

4 }

5 someFunction(1,secondParameterName:2)

Ifaparameterhasanargumentlabel,theargumentmustbelabeledwhenyoucallthefunction.

DefaultParameterValuesYoucandefineadefaultvalueforanyparameterinafunctionbyassigningavaluetotheparameterafterthatparameter’stype.Ifadefaultvalueisdefined,youcanomitthatparameterwhencallingthefunction.

1 funcsomeFunction(parameterWithoutDefault:Int,

parameterWithDefault:Int=12){

Page 177: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 //Ifyouomitthesecondargumentwhencallingthis

function,then

3 //thevalueofparameterWithDefaultis12insidethe

functionbody.

4 }

5 someFunction(parameterWithoutDefault:3,parameterWithDefault:

6)//parameterWithDefaultis6

6 someFunction(parameterWithoutDefault:4)//

parameterWithDefaultis12

Placeparametersthatdon’thavedefaultvaluesatthebeginningofafunction’sparameterlist,beforetheparametersthathavedefaultvalues.Parametersthatdon’thavedefaultvaluesareusuallymoreimportanttothefunction’smeaning—writingthemfirstmakesiteasiertorecognizethatthesamefunctionisbeingcalled,regardlessofwhetheranydefaultparametersareomitted.

VariadicParametersAvariadicparameteracceptszeroormorevaluesofaspecifiedtype.Youuseavariadicparametertospecifythattheparametercanbepassedavaryingnumberofinputvalueswhenthefunctioniscalled.Writevariadicparametersbyinsertingthreeperiodcharacters(...)aftertheparameter’stypename.

Thevaluespassedtoavariadicparameteraremadeavailablewithinthefunction’sbodyasanarrayoftheappropriatetype.Forexample,avariadicparameterwithanameofnumbersandatypeofDouble...ismadeavailablewithinthefunction’sbodyasaconstantarraycallednumbersoftype[Double].

Theexamplebelowcalculatesthearithmeticmean(alsoknownastheaverage)foralistofnumbersofanylength:

1 funcarithmeticMean(_numbers:Double...)->Double{

2 vartotal:Double=0

Page 178: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 fornumberinnumbers{

4 total+=number

5 }

6 returntotal/Double(numbers.count)

7 }

8 arithmeticMean(1,2,3,4,5)

9 //returns3.0,whichisthearithmeticmeanofthesefive

numbers

10 arithmeticMean(3,8.25,18.75)

11 //returns10.0,whichisthearithmeticmeanofthesethree

numbers

NOTE

Afunctionmayhaveatmostonevariadicparameter.

In-OutParametersFunctionparametersareconstantsbydefault.Tryingtochangethevalueofafunctionparameterfromwithinthebodyofthatfunctionresultsinacompile-timeerror.Thismeansthatyoucan’tchangethevalueofaparameterbymistake.Ifyouwantafunctiontomodifyaparameter’svalue,andyouwantthosechangestopersistafterthefunctioncallhasended,definethatparameterasanin-outparameterinstead.

Youwriteanin-outparameterbyplacingtheinoutkeywordrightbeforeaparameter’stype.Anin-outparameterhasavaluethatispassedintothefunction,ismodifiedbythefunction,andispassedbackoutofthefunctiontoreplacetheoriginalvalue.Foradetaileddiscussionofthebehaviorofin-outparametersandassociatedcompileroptimizations,seeIn-OutParameters.

Youcanonlypassavariableastheargumentforanin-outparameter.Youcannotpassaconstantoraliteralvalueastheargument,becauseconstantsandliteralscannotbemodified.Youplaceanampersand(&)directlybeforeavariable’s

Page 179: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

namewhenyoupassitasanargumenttoanin-outparameter,toindicatethatitcanbemodifiedbythefunction.

NOTE

In-outparameterscannothavedefaultvalues,andvariadicparameterscannotbemarkedasinout.

Here’sanexampleofafunctioncalledswapTwoInts(_:_:),whichhastwoin-outintegerparameterscalledaandb:

1 funcswapTwoInts(_a:inoutInt,_b:inoutInt){

2 lettemporaryA=a

3 a=b

4 b=temporaryA

5 }

TheswapTwoInts(_:_:)functionsimplyswapsthevalueofbintoa,andthevalueofaintob.ThefunctionperformsthisswapbystoringthevalueofainatemporaryconstantcalledtemporaryA,assigningthevalueofbtoa,andthenassigningtemporaryAtob.

YoucancalltheswapTwoInts(_:_:)functionwithtwovariablesoftypeInttoswaptheirvalues.NotethatthenamesofsomeIntandanotherIntareprefixedwithanampersandwhentheyarepassedtotheswapTwoInts(_:_:)function:

1 varsomeInt=3

2 varanotherInt=107

3 swapTwoInts(&someInt,&anotherInt)

4 print("someIntisnow\(someInt),andanotherIntisnow\

(anotherInt)")

5 //Prints"someIntisnow107,andanotherIntisnow3"

TheexampleaboveshowsthattheoriginalvaluesofsomeIntandanotherIntaremodifiedbytheswapTwoInts(_:_:)function,eventhoughtheywereoriginallydefinedoutsideofthefunction.

Page 180: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

In-outparametersarenotthesameasreturningavaluefromafunction.TheswapTwoIntsexampleabovedoesnotdefineareturntypeorreturnavalue,butitstillmodifiesthevaluesofsomeIntandanotherInt.In-outparametersareanalternativewayforafunctiontohaveaneffectoutsideofthescopeofitsfunctionbody.

FunctionTypes

Everyfunctionhasaspecificfunctiontype,madeupoftheparametertypesandthereturntypeofthefunction.

Forexample:

1 funcaddTwoInts(_a:Int,_b:Int)->Int{

2 returna+b

3 }

4 funcmultiplyTwoInts(_a:Int,_b:Int)->Int{

5 returna*b

6 }

ThisexampledefinestwosimplemathematicalfunctionscalledaddTwoIntsandmultiplyTwoInts.ThesefunctionseachtaketwoIntvalues,andreturnanIntvalue,whichistheresultofperforminganappropriatemathematicaloperation.

Thetypeofbothofthesefunctionsis(Int,Int)->Int.Thiscanbereadas:

“Afunctionthathastwoparameters,bothoftypeInt,andthatreturnsavalueoftypeInt.”

Here’sanotherexample,forafunctionwithnoparametersorreturnvalue:

1 funcprintHelloWorld(){

2 print("hello,world")

Page 181: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 }

Thetypeofthisfunctionis()->Void,or“afunctionthathasnoparameters,andreturnsVoid.”

UsingFunctionTypesYouusefunctiontypesjustlikeanyothertypesinSwift.Forexample,youcandefineaconstantorvariabletobeofafunctiontypeandassignanappropriatefunctiontothatvariable:

varmathFunction:(Int,Int)->Int=addTwoInts

Thiscanbereadas:

“DefineavariablecalledmathFunction,whichhasatypeof‘afunctionthattakestwoIntvalues,andreturnsanIntvalue.’SetthisnewvariabletorefertothefunctioncalledaddTwoInts.”

TheaddTwoInts(_:_:)functionhasthesametypeasthemathFunctionvariable,andsothisassignmentisallowedbySwift’stype-checker.

YoucannowcalltheassignedfunctionwiththenamemathFunction:

1 print("Result:\(mathFunction(2,3))")

2 //Prints"Result:5"

Adifferentfunctionwiththesamematchingtypecanbeassignedtothesamevariable,inthesamewayasfornonfunctiontypes:

1 mathFunction=multiplyTwoInts

2 print("Result:\(mathFunction(2,3))")

3 //Prints"Result:6"

Aswithanyothertype,youcanleaveittoSwifttoinferthefunctiontypewhen

Page 182: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

youassignafunctiontoaconstantorvariable:

1 letanotherMathFunction=addTwoInts

2 //anotherMathFunctionisinferredtobeoftype(Int,Int)->

Int

FunctionTypesasParameterTypesYoucanuseafunctiontypesuchas(Int,Int)->Intasaparametertypeforanotherfunction.Thisenablesyoutoleavesomeaspectsofafunction’simplementationforthefunction’scallertoprovidewhenthefunctioniscalled.

Here’sanexampletoprinttheresultsofthemathfunctionsfromabove:

1 funcprintMathResult(_mathFunction:(Int,Int)->Int,_a:

Int,_b:Int){

2 print("Result:\(mathFunction(a,b))")

3 }

4 printMathResult(addTwoInts,3,5)

5 //Prints"Result:8"

ThisexampledefinesafunctioncalledprintMathResult(_:_:_:),whichhasthreeparameters.ThefirstparameteriscalledmathFunction,andisoftype(Int,Int)->Int.Youcanpassanyfunctionofthattypeastheargumentforthisfirstparameter.Thesecondandthirdparametersarecalledaandb,andarebothoftypeInt.Theseareusedasthetwoinputvaluesfortheprovidedmathfunction.

WhenprintMathResult(_:_:_:)iscalled,itispassedtheaddTwoInts(_:_:)function,andtheintegervalues3and5.Itcallstheprovidedfunctionwiththevalues3and5,andprintstheresultof8.

TheroleofprintMathResult(_:_:_:)istoprinttheresultofacalltoamathfunctionofanappropriatetype.Itdoesn’tmatterwhatthatfunction’simplementationactuallydoes—itmattersonlythatthefunctionisofthecorrect

Page 183: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

type.ThisenablesprintMathResult(_:_:_:)tohandoffsomeofitsfunctionalitytothecallerofthefunctioninatype-safeway.

FunctionTypesasReturnTypesYoucanuseafunctiontypeasthereturntypeofanotherfunction.Youdothisbywritingacompletefunctiontypeimmediatelyafterthereturnarrow(->)ofthereturningfunction.

ThenextexampledefinestwosimplefunctionscalledstepForward(_:)andstepBackward(_:).ThestepForward(_:)functionreturnsavalueonemorethanitsinputvalue,andthestepBackward(_:)functionreturnsavalueonelessthanitsinputvalue.Bothfunctionshaveatypeof(Int)->Int:

1 funcstepForward(_input:Int)->Int{

2 returninput+1

3 }

4 funcstepBackward(_input:Int)->Int{

5 returninput-1

6 }

Here’safunctioncalledchooseStepFunction(backward:),whosereturntypeis(Int)->Int.ThechooseStepFunction(backward:)functionreturnsthestepForward(_:)functionorthestepBackward(_:)functionbasedonaBooleanparametercalledbackward:

1 funcchooseStepFunction(backward:Bool)->(Int)->Int{

2 returnbackward?stepBackward:stepForward

3 }

YoucannowusechooseStepFunction(backward:)toobtainafunctionthatwillstepinonedirectionortheother:

1 varcurrentValue=3

Page 184: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 letmoveNearerToZero=chooseStepFunction(backward:

currentValue>0)

3 //moveNearerToZeronowreferstothestepBackward()function

TheexampleabovedetermineswhetherapositiveornegativestepisneededtomoveavariablecalledcurrentValueprogressivelyclosertozero.currentValuehasaninitialvalueof3,whichmeansthatcurrentValue>0returnstrue,causingchooseStepFunction(backward:)toreturnthestepBackward(_:)function.AreferencetothereturnedfunctionisstoredinaconstantcalledmoveNearerToZero.

NowthatmoveNearerToZeroreferstothecorrectfunction,itcanbeusedtocounttozero:

1 print("Countingtozero:")

2 //Countingtozero:

3 whilecurrentValue!=0{

4 print("\(currentValue)...")

5 currentValue=moveNearerToZero(currentValue)

6 }

7 print("zero!")

8 //3...

9 //2...

10 //1...

11 //zero!

NestedFunctions

Allofthefunctionsyouhaveencounteredsofarinthischapterhavebeenexamplesofglobalfunctions,whicharedefinedataglobalscope.Youcanalsodefinefunctionsinsidethebodiesofotherfunctions,knownasnestedfunctions.

Page 185: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Nestedfunctionsarehiddenfromtheoutsideworldbydefault,butcanstillbecalledandusedbytheirenclosingfunction.Anenclosingfunctioncanalsoreturnoneofitsnestedfunctionstoallowthenestedfunctiontobeusedinanotherscope.

YoucanrewritethechooseStepFunction(backward:)exampleabovetouseandreturnnestedfunctions:

1 funcchooseStepFunction(backward:Bool)->(Int)->Int{

2 funcstepForward(input:Int)->Int{returninput+1}

3 funcstepBackward(input:Int)->Int{returninput-1}

4 returnbackward?stepBackward:stepForward

5 }

6 varcurrentValue=-4

7 letmoveNearerToZero=chooseStepFunction(backward:

currentValue>0)

8 //moveNearerToZeronowreferstothenestedstepForward()

function

9 whilecurrentValue!=0{

10 print("\(currentValue)...")

11 currentValue=moveNearerToZero(currentValue)

12 }

13 print("zero!")

14 //-4...

15 //-3...

16 //-2...

17 //-1...

18 //zero!

Page 186: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Closures

Closuresareself-containedblocksoffunctionalitythatcanbepassedaroundandusedinyourcode.ClosuresinSwiftaresimilartoblocksinCandObjective-Candtolambdasinotherprogramminglanguages.

Closurescancaptureandstorereferencestoanyconstantsandvariablesfromthecontextinwhichtheyaredefined.Thisisknownasclosingoverthoseconstantsandvariables.Swifthandlesallofthememorymanagementofcapturingforyou.

NOTE

Don’tworryifyouarenotfamiliarwiththeconceptofcapturing.ItisexplainedindetailbelowinCapturingValues.

Globalandnestedfunctions,asintroducedinFunctions,areactuallyspecialcasesofclosures.Closurestakeoneofthreeforms:

Globalfunctionsareclosuresthathaveanameanddonotcaptureanyvalues.

Nestedfunctionsareclosuresthathaveanameandcancapturevaluesfromtheirenclosingfunction.

Closureexpressionsareunnamedclosureswritteninalightweightsyntaxthatcancapturevaluesfromtheirsurroundingcontext.

Swift’sclosureexpressionshaveaclean,clearstyle,withoptimizationsthatencouragebrief,clutter-freesyntaxincommonscenarios.Theseoptimizationsinclude:

Inferringparameterandreturnvaluetypesfromcontext

Implicitreturnsfromsingle-expressionclosures

Shorthandargumentnames

Page 187: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Trailingclosuresyntax

ClosureExpressions

Nestedfunctions,asintroducedinNestedFunctions,areaconvenientmeansofnaminganddefiningself-containedblocksofcodeaspartofalargerfunction.However,itissometimesusefultowriteshorterversionsoffunction-likeconstructswithoutafulldeclarationandname.Thisisparticularlytruewhenyouworkwithfunctionsormethodsthattakefunctionsasoneormoreoftheirarguments.

Closureexpressionsareawaytowriteinlineclosuresinabrief,focusedsyntax.Closureexpressionsprovideseveralsyntaxoptimizationsforwritingclosuresinashortenedformwithoutlossofclarityorintent.Theclosureexpressionexamplesbelowillustratetheseoptimizationsbyrefiningasingleexampleofthesorted(by:)methodoverseveraliterations,eachofwhichexpressesthesamefunctionalityinamoresuccinctway.

TheSortedMethodSwift’sstandardlibraryprovidesamethodcalledsorted(by:),whichsortsanarrayofvaluesofaknowntype,basedontheoutputofasortingclosurethatyouprovide.Onceitcompletesthesortingprocess,thesorted(by:)methodreturnsanewarrayofthesametypeandsizeastheoldone,withitselementsinthecorrectsortedorder.Theoriginalarrayisnotmodifiedbythesorted(by:)method.

Theclosureexpressionexamplesbelowusethesorted(by:)methodtosortanarrayofStringvaluesinreversealphabeticalorder.Here’stheinitialarraytobesorted:

letnames=["Chris","Alex","Ewa","Barry","Daniella"]

Thesorted(by:)methodacceptsaclosurethattakestwoargumentsofthesame

Page 188: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

typeasthearray’scontents,andreturnsaBoolvaluetosaywhetherthefirstvalueshouldappearbeforeorafterthesecondvalueoncethevaluesaresorted.Thesortingclosureneedstoreturntrueifthefirstvalueshouldappearbeforethesecondvalue,andfalseotherwise.

ThisexampleissortinganarrayofStringvalues,andsothesortingclosureneedstobeafunctionoftype(String,String)->Bool.

Onewaytoprovidethesortingclosureistowriteanormalfunctionofthecorrecttype,andtopassitinasanargumenttothesorted(by:)method:

1 funcbackward(_s1:String,_s2:String)->Bool{

2 returns1>s2

3 }

4 varreversedNames=names.sorted(by:backward)

5 //reversedNamesisequalto["Ewa","Daniella","Chris",

"Barry","Alex"]

Ifthefirststring(s1)isgreaterthanthesecondstring(s2),thebackward(_:_:)functionwillreturntrue,indicatingthats1shouldappearbefores2inthesortedarray.Forcharactersinstrings,“greaterthan”means“appearslaterinthealphabetthan”.Thismeansthattheletter"B"is“greaterthan”theletter"A",andthestring"Tom"isgreaterthanthestring"Tim".Thisgivesareversealphabeticalsort,with"Barry"beingplacedbefore"Alex",andsoon.

However,thisisaratherlong-windedwaytowritewhatisessentiallyasingle-expressionfunction(a>b).Inthisexample,itwouldbepreferabletowritethesortingclosureinline,usingclosureexpressionsyntax.

ClosureExpressionSyntaxClosureexpressionsyntaxhasthefollowinggeneralform:

{( parameters )-> returntype in

statements

Page 189: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

}

Theparametersinclosureexpressionsyntaxcanbein-outparameters,buttheycan’thaveadefaultvalue.Variadicparameterscanbeusedifyounamethevariadicparameter.Tuplescanalsobeusedasparametertypesandreturntypes.

Theexamplebelowshowsaclosureexpressionversionofthebackward(_:_:)functionfromabove:

1 reversedNames=names.sorted(by:{(s1:String,s2:String)->

Boolin

2 returns1>s2

3 })

Notethatthedeclarationofparametersandreturntypeforthisinlineclosureisidenticaltothedeclarationfromthebackward(_:_:)function.Inbothcases,itiswrittenas(s1:String,s2:String)->Bool.However,fortheinlineclosureexpression,theparametersandreturntypearewritteninsidethecurlybraces,notoutsideofthem.

Thestartoftheclosure’sbodyisintroducedbytheinkeyword.Thiskeywordindicatesthatthedefinitionoftheclosure’sparametersandreturntypehasfinished,andthebodyoftheclosureisabouttobegin.

Becausethebodyoftheclosureissoshort,itcanevenbewrittenonasingleline:

reversedNames=names.sorted(by:{(s1:String,s2:String)->

Boolinreturns1>s2})

Thisillustratesthattheoverallcalltothesorted(by:)methodhasremainedthesame.Apairofparenthesesstillwraptheentireargumentforthemethod.However,thatargumentisnowaninlineclosure.

Page 190: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

InferringTypeFromContextBecausethesortingclosureispassedasanargumenttoamethod,Swiftcaninferthetypesofitsparametersandthetypeofthevalueitreturns.Thesorted(by:)methodisbeingcalledonanarrayofstrings,soitsargumentmustbeafunctionoftype(String,String)->Bool.Thismeansthatthe(String,String)andBooltypesdonotneedtobewrittenaspartoftheclosureexpression’sdefinition.Becauseallofthetypescanbeinferred,thereturnarrow(->)andtheparenthesesaroundthenamesoftheparameterscanalsobeomitted:

reversedNames=names.sorted(by:{s1,s2inreturns1>s2})

Itisalwayspossibletoinfertheparametertypesandreturntypewhenpassingaclosuretoafunctionormethodasaninlineclosureexpression.Asaresult,youneverneedtowriteaninlineclosureinitsfullestformwhentheclosureisusedasafunctionormethodargument.

Nonetheless,youcanstillmakethetypesexplicitifyouwish,anddoingsoisencouragedifitavoidsambiguityforreadersofyourcode.Inthecaseofthesorted(by:)method,thepurposeoftheclosureisclearfromthefactthatsortingistakingplace,anditissafeforareadertoassumethattheclosureislikelytobeworkingwithStringvalues,becauseitisassistingwiththesortingofanarrayofstrings.

ImplicitReturnsfromSingle-ExpressionClosuresSingle-expressionclosurescanimplicitlyreturntheresultoftheirsingleexpressionbyomittingthereturnkeywordfromtheirdeclaration,asinthisversionofthepreviousexample:

reversedNames=names.sorted(by:{s1,s2ins1>s2})

Here,thefunctiontypeofthesorted(by:)method’sargumentmakesitclearthataBoolvaluemustbereturnedbytheclosure.Becausetheclosure’sbodycontainsasingleexpression(s1>s2)thatreturnsaBoolvalue,thereisnoambiguity,andthereturnkeywordcanbeomitted.

Page 191: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ShorthandArgumentNamesSwiftautomaticallyprovidesshorthandargumentnamestoinlineclosures,whichcanbeusedtorefertothevaluesoftheclosure’sargumentsbythenames$0,$1,$2,andsoon.

Ifyouusetheseshorthandargumentnameswithinyourclosureexpression,youcanomittheclosure’sargumentlistfromitsdefinition,andthenumberandtypeoftheshorthandargumentnameswillbeinferredfromtheexpectedfunctiontype.Theinkeywordcanalsobeomitted,becausetheclosureexpressionismadeupentirelyofitsbody:

reversedNames=names.sorted(by:{$0>$1})

Here,$0and$1refertotheclosure’sfirstandsecondStringarguments.

OperatorMethodsThere’sactuallyanevenshorterwaytowritetheclosureexpressionabove.Swift’sStringtypedefinesitsstring-specificimplementationofthegreater-thanoperator(>)asamethodthathastwoparametersoftypeString,andreturnsavalueoftypeBool.Thisexactlymatchesthemethodtypeneededbythesorted(by:)method.Therefore,youcansimplypassinthegreater-thanoperator,andSwiftwillinferthatyouwanttouseitsstring-specificimplementation:

reversedNames=names.sorted(by:>)

Formoreaboutoperatormethod,seeOperatorMethods.

TrailingClosures

Ifyouneedtopassaclosureexpressiontoafunctionasthefunction’sfinalargumentandtheclosureexpressionislong,itcanbeusefultowriteitasa

Page 192: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

trailingclosureinstead.Atrailingclosureiswrittenafterthefunctioncall’sparentheses,eventhoughitisstillanargumenttothefunction.Whenyouusethetrailingclosuresyntax,youdon’twritetheargumentlabelfortheclosureaspartofthefunctioncall.

1 funcsomeFunctionThatTakesAClosure(closure:()->Void){

2 //functionbodygoeshere

3 }

4

5 //Here'showyoucallthisfunctionwithoutusingatrailing

closure:

6

7 someFunctionThatTakesAClosure(closure:{

8 //closure'sbodygoeshere

9 })

10

11 //Here'showyoucallthisfunctionwithatrailingclosure

instead:

12

13 someFunctionThatTakesAClosure(){

14 //trailingclosure'sbodygoeshere

15 }

Thestring-sortingclosurefromtheClosureExpressionSyntaxsectionabovecanbewrittenoutsideofthesorted(by:)method’sparenthesesasatrailingclosure:

reversedNames=names.sorted(){$0>$1}

Ifaclosureexpressionisprovidedasthefunctionormethod’sonlyargumentandyouprovidethatexpressionasatrailingclosure,youdonotneedtowriteapairofparentheses()afterthefunctionormethod’snamewhenyoucallthefunction:

Page 193: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

reversedNames=names.sorted{$0>$1}

Trailingclosuresaremostusefulwhentheclosureissufficientlylongthatitisnotpossibletowriteitinlineonasingleline.Asanexample,Swift’sArraytypehasamap(_:)methodwhichtakesaclosureexpressionasitssingleargument.Theclosureiscalledonceforeachiteminthearray,andreturnsanalternativemappedvalue(possiblyofsomeothertype)forthatitem.Thenatureofthemappingandthetypeofthereturnedvalueisleftuptotheclosuretospecify.

Afterapplyingtheprovidedclosuretoeacharrayelement,themap(_:)methodreturnsanewarraycontainingallofthenewmappedvalues,inthesameorderastheircorrespondingvaluesintheoriginalarray.

Here’showyoucanusethemap(_:)methodwithatrailingclosuretoconvertanarrayofIntvaluesintoanarrayofStringvalues.Thearray[16,58,510]isusedtocreatethenewarray["OneSix","FiveEight","FiveOneZero"]:

1 letdigitNames=[

2 0:"Zero",1:"One",2:"Two",3:"Three",4:"Four",

3 5:"Five",6:"Six",7:"Seven",8:"Eight",9:"Nine"

4 ]

5 letnumbers=[16,58,510]

ThecodeabovecreatesadictionaryofmappingsbetweentheintegerdigitsandEnglish-languageversionsoftheirnames.Italsodefinesanarrayofintegers,readytobeconvertedintostrings.

YoucannowusethenumbersarraytocreateanarrayofStringvalues,bypassingaclosureexpressiontothearray’smap(_:)methodasatrailingclosure:

1 letstrings=numbers.map{(number)->Stringin

2 varnumber=number

3 varoutput=""

4 repeat{

5 output=digitNames[number%10]!+output

Page 194: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 number/=10

7 }whilenumber>0

8 returnoutput

9 }

10 //stringsisinferredtobeoftype[String]

11 //itsvalueis["OneSix","FiveEight","FiveOneZero"]

Themap(_:)methodcallstheclosureexpressiononceforeachiteminthearray.Youdonotneedtospecifythetypeoftheclosure’sinputparameter,number,becausethetypecanbeinferredfromthevaluesinthearraytobemapped.

Inthisexample,thevariablenumberisinitializedwiththevalueoftheclosure’snumberparameter,sothatthevaluecanbemodifiedwithintheclosurebody.(Theparameterstofunctionsandclosuresarealwaysconstants.)TheclosureexpressionalsospecifiesareturntypeofString,toindicatethetypethatwillbestoredinthemappedoutputarray.

Theclosureexpressionbuildsastringcalledoutputeachtimeitiscalled.Itcalculatesthelastdigitofnumberbyusingtheremainderoperator(number%10),andusesthisdigittolookupanappropriatestringinthedigitNamesdictionary.Theclosurecanbeusedtocreateastringrepresentationofanyintegergreaterthanzero.

NOTE

ThecalltothedigitNamesdictionary’ssubscriptisfollowedbyanexclamationmark(!),becausedictionarysubscriptsreturnanoptionalvaluetoindicatethatthedictionarylookupcanfailifthekeydoesnotexist.Intheexampleabove,itisguaranteedthatnumber%10willalwaysbeavalidsubscriptkeyforthedigitNamesdictionary,andsoanexclamationmarkisusedtoforce-unwraptheStringvaluestoredinthesubscript’soptionalreturnvalue.

ThestringretrievedfromthedigitNamesdictionaryisaddedtothefrontofoutput,effectivelybuildingastringversionofthenumberinreverse.(Theexpressionnumber%10givesavalueof6for16,8for58,and0for510.)

Thenumbervariableisthendividedby10.Becauseitisaninteger,itisroundeddownduringthedivision,so16becomes1,58becomes5,and510becomes51.

Page 195: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theprocessisrepeateduntilnumberisequalto0,atwhichpointtheoutputstringisreturnedbytheclosure,andisaddedtotheoutputarraybythemap(_:)method.

Theuseoftrailingclosuresyntaxintheexampleaboveneatlyencapsulatestheclosure’sfunctionalityimmediatelyafterthefunctionthatclosuresupports,withoutneedingtowraptheentireclosurewithinthemap(_:)method’souterparentheses.

CapturingValues

Aclosurecancaptureconstantsandvariablesfromthesurroundingcontextinwhichitisdefined.Theclosurecanthenrefertoandmodifythevaluesofthoseconstantsandvariablesfromwithinitsbody,eveniftheoriginalscopethatdefinedtheconstantsandvariablesnolongerexists.

InSwift,thesimplestformofaclosurethatcancapturevaluesisanestedfunction,writtenwithinthebodyofanotherfunction.Anestedfunctioncancaptureanyofitsouterfunction’sargumentsandcanalsocaptureanyconstantsandvariablesdefinedwithintheouterfunction.

Here’sanexampleofafunctioncalledmakeIncrementer,whichcontainsanestedfunctioncalledincrementer.Thenestedincrementer()functioncapturestwovalues,runningTotalandamount,fromitssurroundingcontext.Aftercapturingthesevalues,incrementerisreturnedbymakeIncrementerasaclosurethatincrementsrunningTotalbyamounteachtimeitiscalled.

1 funcmakeIncrementer(forIncrementamount:Int)->()->Int{

2 varrunningTotal=0

3 funcincrementer()->Int{

4 runningTotal+=amount

5 returnrunningTotal

6 }

7 returnincrementer

Page 196: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 }

ThereturntypeofmakeIncrementeris()->Int.Thismeansthatitreturnsafunction,ratherthanasimplevalue.Thefunctionitreturnshasnoparameters,andreturnsanIntvalueeachtimeitiscalled.Tolearnhowfunctionscanreturnotherfunctions,seeFunctionTypesasReturnTypes.

ThemakeIncrementer(forIncrement:)functiondefinesanintegervariablecalledrunningTotal,tostorethecurrentrunningtotaloftheincrementerthatwillbereturned.Thisvariableisinitializedwithavalueof0.

ThemakeIncrementer(forIncrement:)functionhasasingleIntparameterwithanargumentlabelofforIncrement,andaparameternameofamount.TheargumentvaluepassedtothisparameterspecifieshowmuchrunningTotalshouldbeincrementedbyeachtimethereturnedincrementerfunctioniscalled.ThemakeIncrementerfunctiondefinesanestedfunctioncalledincrementer,whichperformstheactualincrementing.ThisfunctionsimplyaddsamounttorunningTotal,andreturnstheresult.

Whenconsideredinisolation,thenestedincrementer()functionmightseemunusual:

1 funcincrementer()->Int{

2 runningTotal+=amount

3 returnrunningTotal

4 }

Theincrementer()functiondoesn’thaveanyparameters,andyetitreferstorunningTotalandamountfromwithinitsfunctionbody.ItdoesthisbycapturingareferencetorunningTotalandamountfromthesurroundingfunctionandusingthemwithinitsownfunctionbody.CapturingbyreferenceensuresthatrunningTotalandamountdonotdisappearwhenthecalltomakeIncrementerends,andalsoensuresthatrunningTotalisavailablethenexttimetheincrementerfunctioniscalled.

NOTE

Page 197: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Asanoptimization,Swiftmayinsteadcaptureandstoreacopyofavalueifthatvalueisnotmutatedbyaclosure,andifthevalueisnotmutatedaftertheclosureiscreated.

Swiftalsohandlesallmemorymanagementinvolvedindisposingofvariableswhentheyarenolongerneeded.

Here’sanexampleofmakeIncrementerinaction:

letincrementByTen=makeIncrementer(forIncrement:10)

ThisexamplesetsaconstantcalledincrementByTentorefertoanincrementerfunctionthatadds10toitsrunningTotalvariableeachtimeitiscalled.Callingthefunctionmultipletimesshowsthisbehaviorinaction:

1 incrementByTen()

2 //returnsavalueof10

3 incrementByTen()

4 //returnsavalueof20

5 incrementByTen()

6 //returnsavalueof30

Ifyoucreateasecondincrementer,itwillhaveitsownstoredreferencetoanew,separaterunningTotalvariable:

1 letincrementBySeven=makeIncrementer(forIncrement:7)

2 incrementBySeven()

3 //returnsavalueof7

Callingtheoriginalincrementer(incrementByTen)againcontinuestoincrementitsownrunningTotalvariable,anddoesnotaffectthevariablecapturedbyincrementBySeven:

1 incrementByTen()

2 //returnsavalueof40

Page 198: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Ifyouassignaclosuretoapropertyofaclassinstance,andtheclosurecapturesthatinstancebyreferringtotheinstanceoritsmembers,youwillcreateastrongreferencecyclebetweentheclosureandtheinstance.Swiftusescaptureliststobreakthesestrongreferencecycles.Formoreinformation,seeStrongReferenceCyclesforClosures.

ClosuresAreReferenceTypes

Intheexampleabove,incrementBySevenandincrementByTenareconstants,buttheclosurestheseconstantsrefertoarestillabletoincrementtherunningTotalvariablesthattheyhavecaptured.Thisisbecausefunctionsandclosuresarereferencetypes.

Wheneveryouassignafunctionoraclosuretoaconstantoravariable,youareactuallysettingthatconstantorvariabletobeareferencetothefunctionorclosure.Intheexampleabove,itisthechoiceofclosurethatincrementByTenreferstothatisconstant,andnotthecontentsoftheclosureitself.

Thisalsomeansthatifyouassignaclosuretotwodifferentconstantsorvariables,bothofthoseconstantsorvariablesrefertothesameclosure.

1 letalsoIncrementByTen=incrementByTen

2 alsoIncrementByTen()

3 //returnsavalueof50

4

5 incrementByTen()

6 //returnsavalueof60

TheexampleaboveshowsthatcallingalsoIncrementByTenisthesameascallingincrementByTen.Becausebothofthemrefertothesameclosure,theybothincrementandreturnthesamerunningtotal.

Page 199: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

EscapingClosures

Aclosureissaidtoescapeafunctionwhentheclosureispassedasanargumenttothefunction,butiscalledafterthefunctionreturns.Whenyoudeclareafunctionthattakesaclosureasoneofitsparameters,youcanwrite@escapingbeforetheparameter’stypetoindicatethattheclosureisallowedtoescape.

Onewaythataclosurecanescapeisbybeingstoredinavariablethatisdefinedoutsidethefunction.Asanexample,manyfunctionsthatstartanasynchronousoperationtakeaclosureargumentasacompletionhandler.Thefunctionreturnsafteritstartstheoperation,buttheclosureisn’tcalleduntiltheoperationiscompleted—theclosureneedstoescape,tobecalledlater.Forexample:

1 varcompletionHandlers:[()->Void]=[]

2 funcsomeFunctionWithEscapingClosure(completionHandler:

@escaping()->Void){

3 completionHandlers.append(completionHandler)

4 }

ThesomeFunctionWithEscapingClosure(_:)functiontakesaclosureasitsargumentandaddsittoanarraythat’sdeclaredoutsidethefunction.Ifyoudidn’tmarktheparameterofthisfunctionwith@escaping,youwouldgetacompile-timeerror.

Markingaclosurewith@escapingmeansyouhavetorefertoselfexplicitlywithintheclosure.Forexample,inthecodebelow,theclosurepassedtosomeFunctionWithEscapingClosure(_:)isanescapingclosure,whichmeansitneedstorefertoselfexplicitly.Incontrast,theclosurepassedtosomeFunctionWithNonescapingClosure(_:)isanonescapingclosure,whichmeansitcanrefertoselfimplicitly.

1 funcsomeFunctionWithNonescapingClosure(closure:()->Void){

2 closure()

3 }

4

Page 200: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 classSomeClass{

6 varx=10

7 funcdoSomething(){

8 someFunctionWithEscapingClosure{self.x=100}

9 someFunctionWithNonescapingClosure{x=200}

10 }

11 }

12

13 letinstance=SomeClass()

14 instance.doSomething()

15 print(instance.x)

16 //Prints"200"

17

18 completionHandlers.first?()

19 print(instance.x)

20 //Prints"100"

Autoclosures

Anautoclosureisaclosurethatisautomaticallycreatedtowrapanexpressionthat’sbeingpassedasanargumenttoafunction.Itdoesn’ttakeanyarguments,andwhenit’scalled,itreturnsthevalueoftheexpressionthat’swrappedinsideofit.Thissyntacticconvenienceletsyouomitbracesaroundafunction’sparameterbywritinganormalexpressioninsteadofanexplicitclosure.

It’scommontocallfunctionsthattakeautoclosures,butit’snotcommontoimplementthatkindoffunction.Forexample,theassert(condition:message:file:line:)functiontakesanautoclosureforitsconditionandmessageparameters;itsconditionparameterisevaluatedonlyindebugbuildsanditsmessageparameterisevaluatedonlyifconditionisfalse.

Page 201: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Anautoclosureletsyoudelayevaluation,becausethecodeinsideisn’trununtilyoucalltheclosure.Delayingevaluationisusefulforcodethathassideeffectsoriscomputationallyexpensive,becauseitletsyoucontrolwhenthatcodeisevaluated.Thecodebelowshowshowaclosuredelaysevaluation.

1 varcustomersInLine=["Chris","Alex","Ewa","Barry",

"Daniella"]

2 print(customersInLine.count)

3 //Prints"5"

4

5 letcustomerProvider={customersInLine.remove(at:0)}

6 print(customersInLine.count)

7 //Prints"5"

8

9 print("Nowserving\(customerProvider())!")

10 //Prints"NowservingChris!"

11 print(customersInLine.count)

12 //Prints"4"

EventhoughthefirstelementofthecustomersInLinearrayisremovedbythecodeinsidetheclosure,thearrayelementisn’tremoveduntiltheclosureisactuallycalled.Iftheclosureisnevercalled,theexpressioninsidetheclosureisneverevaluated,whichmeansthearrayelementisneverremoved.NotethatthetypeofcustomerProviderisnotStringbut()->String—afunctionwithnoparametersthatreturnsastring.

Yougetthesamebehaviorofdelayedevaluationwhenyoupassaclosureasanargumenttoafunction.

1 //customersInLineis["Alex","Ewa","Barry","Daniella"]

2 funcserve(customercustomerProvider:()->String){

3 print("Nowserving\(customerProvider())!")

4 }

Page 202: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 serve(customer:{customersInLine.remove(at:0)})

6 //Prints"NowservingAlex!"

Theserve(customer:)functioninthelistingabovetakesanexplicitclosurethatreturnsacustomer’sname.Theversionofserve(customer:)belowperformsthesameoperationbut,insteadoftakinganexplicitclosure,ittakesanautoclosurebymarkingitsparameter’stypewiththe@autoclosureattribute.NowyoucancallthefunctionasifittookaStringargumentinsteadofaclosure.Theargumentisautomaticallyconvertedtoaclosure,becausethecustomerProviderparameter’stypeismarkedwiththe@autoclosureattribute.

1 //customersInLineis["Ewa","Barry","Daniella"]

2 funcserve(customercustomerProvider:@autoclosure()->

String){

3 print("Nowserving\(customerProvider())!")

4 }

5 serve(customer:customersInLine.remove(at:0))

6 //Prints"NowservingEwa!"

NOTE

Overusingautoclosurescanmakeyourcodehardtounderstand.Thecontextandfunctionnameshouldmakeitclearthatevaluationisbeingdeferred.

Ifyouwantanautoclosurethatisallowedtoescape,useboththe@[email protected]@escapingattributeisdescribedaboveinEscapingClosures.

1 //customersInLineis["Barry","Daniella"]

2 varcustomerProviders:[()->String]=[]

3 funccollectCustomerProviders(_customerProvider:@autoclosure

@escaping()->String){

4 customerProviders.append(customerProvider)

5 }

Page 203: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 collectCustomerProviders(customersInLine.remove(at:0))

7 collectCustomerProviders(customersInLine.remove(at:0))

8

9 print("Collected\(customerProviders.count)closures.")

10 //Prints"Collected2closures."

11 forcustomerProviderincustomerProviders{

12 print("Nowserving\(customerProvider())!")

13 }

14 //Prints"NowservingBarry!"

15 //Prints"NowservingDaniella!"

Inthecodeabove,insteadofcallingtheclosurepassedtoitasitscustomerProviderargument,thecollectCustomerProviders(_:)functionappendstheclosuretothecustomerProvidersarray.Thearrayisdeclaredoutsidethescopeofthefunction,whichmeanstheclosuresinthearraycanbeexecutedafterthefunctionreturns.Asaresult,thevalueofthecustomerProviderargumentmustbeallowedtoescapethefunction’sscope.

Page 204: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Enumerations

Anenumerationdefinesacommontypeforagroupofrelatedvaluesandenablesyoutoworkwiththosevaluesinatype-safewaywithinyourcode.

IfyouarefamiliarwithC,youwillknowthatCenumerationsassignrelatednamestoasetofintegervalues.EnumerationsinSwiftaremuchmoreflexible,anddon’thavetoprovideavalueforeachcaseoftheenumeration.Ifavalue(knownasarawvalue)isprovidedforeachenumerationcase,thevaluecanbeastring,acharacter,oravalueofanyintegerorfloating-pointtype.

Alternatively,enumerationcasescanspecifyassociatedvaluesofanytypetobestoredalongwitheachdifferentcasevalue,muchasunionsorvariantsdoinotherlanguages.Youcandefineacommonsetofrelatedcasesaspartofoneenumeration,eachofwhichhasadifferentsetofvaluesofappropriatetypesassociatedwithit.

EnumerationsinSwiftarefirst-classtypesintheirownright.Theyadoptmanyfeaturestraditionallysupportedonlybyclasses,suchascomputedpropertiestoprovideadditionalinformationabouttheenumeration’scurrentvalue,andinstancemethodstoprovidefunctionalityrelatedtothevaluestheenumerationrepresents.Enumerationscanalsodefineinitializerstoprovideaninitialcasevalue;canbeextendedtoexpandtheirfunctionalitybeyondtheiroriginalimplementation;andcanconformtoprotocolstoprovidestandardfunctionality.

Formoreaboutthesecapabilities,seeProperties,Methods,Initialization,Extensions,andProtocols.

EnumerationSyntax

Youintroduceenumerationswiththeenumkeywordandplacetheirentiredefinitionwithinapairofbraces:

Page 205: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 enumSomeEnumeration{

2 //enumerationdefinitiongoeshere

3 }

Here’sanexampleforthefourmainpointsofacompass:

1 enumCompassPoint{

2 casenorth

3 casesouth

4 caseeast

5 casewest

6 }

Thevaluesdefinedinanenumeration(suchasnorth,south,east,andwest)areitsenumerationcases.Youusethecasekeywordtointroducenewenumerationcases.

NOTE

Swiftenumerationcasesdon’thaveanintegervaluesetbydefault,unlikelanguageslikeCandObjective-C.IntheCompassPointexampleabove,north,south,eastandwestdon’timplicitlyequal0,1,2and3.Instead,thedifferentenumerationcasesarevaluesintheirownright,withanexplicitlydefinedtypeofCompassPoint.

Multiplecasescanappearonasingleline,separatedbycommas:

1 enumPlanet{

2 casemercury,venus,earth,mars,jupiter,saturn,uranus,

neptune

3 }

Eachenumerationdefinitiondefinesanewtype.LikeothertypesinSwift,theirnames(suchasCompassPointandPlanet)startwithacapitalletter.Giveenumerationtypessingularratherthanpluralnames,sothattheyreadasself-evident:

Page 206: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

vardirectionToHead=CompassPoint.west

ThetypeofdirectionToHeadisinferredwhenit’sinitializedwithoneofthepossiblevaluesofCompassPoint.OncedirectionToHeadisdeclaredasaCompassPoint,youcansetittoadifferentCompassPointvalueusingashorterdotsyntax:

directionToHead=.east

ThetypeofdirectionToHeadisalreadyknown,andsoyoucandropthetypewhensettingitsvalue.Thismakesforhighlyreadablecodewhenworkingwithexplicitlytypedenumerationvalues.

MatchingEnumerationValueswithaSwitchStatement

Youcanmatchindividualenumerationvalueswithaswitchstatement:

1 directionToHead=.south

2 switchdirectionToHead{

3 case.north:

4 print("Lotsofplanetshaveanorth")

5 case.south:

6 print("Watchoutforpenguins")

7 case.east:

8 print("Wherethesunrises")

9 case.west:

10 print("Wheretheskiesareblue")

11 }

12 //Prints"Watchoutforpenguins"

Youcanreadthiscodeas:

Page 207: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

“ConsiderthevalueofdirectionToHead.Inthecasewhereitequals.north,print"Lotsofplanetshaveanorth".Inthecasewhereitequals.south,print"Watchoutforpenguins".”

…andsoon.

AsdescribedinControlFlow,aswitchstatementmustbeexhaustivewhenconsideringanenumeration’scases.Ifthecasefor.westisomitted,thiscodedoesn’tcompile,becauseitdoesn’tconsiderthecompletelistofCompassPointcases.Requiringexhaustivenessensuresthatenumerationcasesaren’taccidentallyomitted.

Whenitisn’tappropriatetoprovideacaseforeveryenumerationcase,youcanprovideadefaultcasetocoveranycasesthataren’taddressedexplicitly:

1 letsomePlanet=Planet.earth

2 switchsomePlanet{

3 case.earth:

4 print("Mostlyharmless")

5 default:

6 print("Notasafeplaceforhumans")

7 }

8 //Prints"Mostlyharmless"

IteratingoverEnumerationCases

Forsomeenumerations,it’susefultohaveacollectionofallofthatenumeration’scases.Youenablethisbywriting:CaseIterableaftertheenumeration’sname.SwiftexposesacollectionofallthecasesasanallCasespropertyoftheenumerationtype.Here’sanexample:

1 enumBeverage:CaseIterable{

2 casecoffee,tea,juice

Page 208: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 }

4 letnumberOfChoices=Beverage.allCases.count

5 print("\(numberOfChoices)beveragesavailable")

6 //Prints"3beveragesavailable"

Intheexampleabove,youwriteBeverage.allCasestoaccessacollectionthatcontainsallofthecasesoftheBeverageenumeration.YoucanuseallCaseslikeanyothercollection—thecollection’selementsareinstancesoftheenumerationtype,sointhiscasethey’reBeveragevalues.Theexampleabovecountshowmanycasesthereare,andtheexamplebelowusesaforlooptoiterateoverallthecases.

1 forbeverageinBeverage.allCases{

2 print(beverage)

3 }

4 //coffee

5 //tea

6 //juice

ThesyntaxusedintheexamplesabovemarkstheenumerationasconformingtotheCaseIterableprotocol.Forinformationaboutprotocols,seeProtocols.

AssociatedValues

Theexamplesintheprevioussectionshowhowthecasesofanenumerationareadefined(andtyped)valueintheirownright.YoucansetaconstantorvariabletoPlanet.earth,andcheckforthisvaluelater.However,it’ssometimesusefultobeabletostorevaluesofothertypesalongsidethesecasevalues.Thisadditionalinformationiscalledanassociatedvalue,anditvarieseachtimeyouusethatcaseasavalueinyourcode.

YoucandefineSwiftenumerationstostoreassociatedvaluesofanygiventype,

Page 209: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

andthevaluetypescanbedifferentforeachcaseoftheenumerationifneeded.Enumerationssimilartotheseareknownasdiscriminatedunions,taggedunions,orvariantsinotherprogramminglanguages.

Forexample,supposeaninventorytrackingsystemneedstotrackproductsbytwodifferenttypesofbarcode.Someproductsarelabeledwith1DbarcodesinUPCformat,whichusesthenumbers0to9.Eachbarcodehasanumbersystemdigit,followedbyfivemanufacturercodedigitsandfiveproductcodedigits.Thesearefollowedbyacheckdigittoverifythatthecodehasbeenscannedcorrectly:

Otherproductsarelabeledwith2DbarcodesinQRcodeformat,whichcanuseanyISO8859-1characterandcanencodeastringupto2,953characterslong:

It’sconvenientforaninventorytrackingsystemtostoreUPCbarcodesasatupleoffourintegers,andQRcodebarcodesasastringofanylength.

InSwift,anenumerationtodefineproductbarcodesofeithertypemightlooklikethis:

1 enumBarcode{

2 caseupc(Int,Int,Int,Int)

3 caseqrCode(String)

Page 210: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 }

Thiscanbereadas:

“DefineanenumerationtypecalledBarcode,whichcantakeeitheravalueofupcwithanassociatedvalueoftype(Int,Int,Int,Int),oravalueofqrCodewithanassociatedvalueoftypeString.”

Thisdefinitiondoesn’tprovideanyactualIntorStringvalues—itjustdefinesthetypeofassociatedvaluesthatBarcodeconstantsandvariablescanstorewhentheyareequaltoBarcode.upcorBarcode.qrCode.

Youcanthencreatenewbarcodesusingeithertype:

varproductBarcode=Barcode.upc(8,85909,51226,3)

ThisexamplecreatesanewvariablecalledproductBarcodeandassignsitavalueofBarcode.upcwithanassociatedtuplevalueof(8,85909,51226,3).

Youcanassignthesameproductadifferenttypeofbarcode:

productBarcode=.qrCode("ABCDEFGHIJKLMNOP")

Atthispoint,theoriginalBarcode.upcanditsintegervaluesarereplacedbythenewBarcode.qrCodeanditsstringvalue.ConstantsandvariablesoftypeBarcodecanstoreeithera.upcora.qrCode(togetherwiththeirassociatedvalues),buttheycanstoreonlyoneofthematanygiventime.

Youcancheckthedifferentbarcodetypesusingaswitchstatement,similartotheexampleinMatchingEnumerationValueswithaSwitchStatement.Thistime,however,theassociatedvaluesareextractedaspartoftheswitchstatement.Youextracteachassociatedvalueasaconstant(withtheletprefix)oravariable(withthevarprefix)forusewithintheswitchcase’sbody:

1 switchproductBarcode{

2 case.upc(letnumberSystem,letmanufacturer,letproduct,let

Page 211: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

check):

3 print("UPC:\(numberSystem),\(manufacturer),\(product),\

(check).")

4 case.qrCode(letproductCode):

5 print("QRcode:\(productCode).")

6 }

7 //Prints"QRcode:ABCDEFGHIJKLMNOP."

Ifalloftheassociatedvaluesforanenumerationcaseareextractedasconstants,orifallareextractedasvariables,youcanplaceasinglevarorletannotationbeforethecasename,forbrevity:

1 switchproductBarcode{

2 caselet.upc(numberSystem,manufacturer,product,check):

3 print("UPC:\(numberSystem),\(manufacturer),\(product),

\(check).")

4 caselet.qrCode(productCode):

5 print("QRcode:\(productCode).")

6 }

7 //Prints"QRcode:ABCDEFGHIJKLMNOP."

RawValues

ThebarcodeexampleinAssociatedValuesshowshowcasesofanenumerationcandeclarethattheystoreassociatedvaluesofdifferenttypes.Asanalternativetoassociatedvalues,enumerationcasescancomeprepopulatedwithdefaultvalues(calledrawvalues),whichareallofthesametype.

Here’sanexamplethatstoresrawASCIIvaluesalongsidenamedenumerationcases:

Page 212: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 enumASCIIControlCharacter:Character{

2 casetab="\t"

3 caselineFeed="\n"

4 casecarriageReturn="\r"

5 }

Here,therawvaluesforanenumerationcalledASCIIControlCharacteraredefinedtobeoftypeCharacter,andaresettosomeofthemorecommonASCIIcontrolcharacters.CharactervaluesaredescribedinStringsandCharacters.

Rawvaluescanbestrings,characters,oranyoftheintegerorfloating-pointnumbertypes.Eachrawvaluemustbeuniquewithinitsenumerationdeclaration.

NOTE

Rawvaluesarenotthesameasassociatedvalues.Rawvaluesaresettoprepopulatedvalueswhenyoufirstdefinetheenumerationinyourcode,likethethreeASCIIcodesabove.Therawvalueforaparticularenumerationcaseisalwaysthesame.Associatedvaluesaresetwhenyoucreateanewconstantorvariablebasedononeoftheenumeration’scases,andcanbedifferenteachtimeyoudoso.

ImplicitlyAssignedRawValuesWhenyou’reworkingwithenumerationsthatstoreintegerorstringrawvalues,youdon’thavetoexplicitlyassignarawvalueforeachcase.Whenyoudon’t,Swiftautomaticallyassignsthevaluesforyou.

Forexample,whenintegersareusedforrawvalues,theimplicitvalueforeachcaseisonemorethanthepreviouscase.Ifthefirstcasedoesn’thaveavalueset,itsvalueis0.

TheenumerationbelowisarefinementoftheearlierPlanetenumeration,withintegerrawvaluestorepresenteachplanet’sorderfromthesun:

1 enumPlanet:Int{

Page 213: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 casemercury=1,venus,earth,mars,jupiter,saturn,

uranus,neptune

3 }

Intheexampleabove,Planet.mercuryhasanexplicitrawvalueof1,Planet.venushasanimplicitrawvalueof2,andsoon.

Whenstringsareusedforrawvalues,theimplicitvalueforeachcaseisthetextofthatcase’sname.

TheenumerationbelowisarefinementoftheearlierCompassPointenumeration,withstringrawvaluestorepresenteachdirection’sname:

1 enumCompassPoint:String{

2 casenorth,south,east,west

3 }

Intheexampleabove,CompassPoint.southhasanimplicitrawvalueof"south",andsoon.

YouaccesstherawvalueofanenumerationcasewithitsrawValueproperty:

1 letearthsOrder=Planet.earth.rawValue

2 //earthsOrderis3

3

4 letsunsetDirection=CompassPoint.west.rawValue

5 //sunsetDirectionis"west"

InitializingfromaRawValueIfyoudefineanenumerationwitharaw-valuetype,theenumerationautomaticallyreceivesaninitializerthattakesavalueoftherawvalue’stype(asaparametercalledrawValue)andreturnseitheranenumerationcaseornil.Youcanusethisinitializertotrytocreateanewinstanceoftheenumeration.

Page 214: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThisexampleidentifiesUranusfromitsrawvalueof7:

1 letpossiblePlanet=Planet(rawValue:7)

2 //possiblePlanetisoftypePlanet?andequalsPlanet.uranus

NotallpossibleIntvalueswillfindamatchingplanet,however.Becauseofthis,therawvalueinitializeralwaysreturnsanoptionalenumerationcase.Intheexampleabove,possiblePlanetisoftypePlanet?,or“optionalPlanet.”

NOTE

Therawvalueinitializerisafailableinitializer,becausenoteveryrawvaluewillreturnanenumerationcase.Formoreinformation,seeFailableInitializers.

Ifyoutrytofindaplanetwithapositionof11,theoptionalPlanetvaluereturnedbytherawvalueinitializerwillbenil:

1 letpositionToFind=11

2 ifletsomePlanet=Planet(rawValue:positionToFind){

3 switchsomePlanet{

4 case.earth:

5 print("Mostlyharmless")

6 default:

7 print("Notasafeplaceforhumans")

8 }

9 }else{

10 print("Thereisn'taplanetatposition\

(positionToFind)")

11 }

12 //Prints"Thereisn'taplanetatposition11"

Thisexampleusesoptionalbindingtotrytoaccessaplanetwitharawvalueof11.ThestatementifletsomePlanet=Planet(rawValue:11)createsanoptionalPlanet,andsetssomePlanettothevalueofthatoptionalPlanetifitcan

Page 215: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

beretrieved.Inthiscase,itisn’tpossibletoretrieveaplanetwithapositionof11,andsotheelsebranchisexecutedinstead.

RecursiveEnumerations

Arecursiveenumerationisanenumerationthathasanotherinstanceoftheenumerationastheassociatedvalueforoneormoreoftheenumerationcases.Youindicatethatanenumerationcaseisrecursivebywritingindirectbeforeit,whichtellsthecompilertoinsertthenecessarylayerofindirection.

Forexample,hereisanenumerationthatstoressimplearithmeticexpressions:

1 enumArithmeticExpression{

2 casenumber(Int)

3 indirectcaseaddition(ArithmeticExpression,

ArithmeticExpression)

4 indirectcasemultiplication(ArithmeticExpression,

ArithmeticExpression)

5 }

Youcanalsowriteindirectbeforethebeginningoftheenumerationtoenableindirectionforalloftheenumeration’scasesthathaveanassociatedvalue:

1 indirectenumArithmeticExpression{

2 casenumber(Int)

3 caseaddition(ArithmeticExpression,ArithmeticExpression)

4 casemultiplication(ArithmeticExpression,

ArithmeticExpression)

5 }

Thisenumerationcanstorethreekindsofarithmeticexpressions:aplainnumber,theadditionoftwoexpressions,andthemultiplicationoftwo

Page 216: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

expressions.Theadditionandmultiplicationcaseshaveassociatedvaluesthatarealsoarithmeticexpressions—theseassociatedvaluesmakeitpossibletonestexpressions.Forexample,theexpression(5+4)*2hasanumberontheright-handsideofthemultiplicationandanotherexpressionontheleft-handsideofthemultiplication.Becausethedataisnested,theenumerationusedtostorethedataalsoneedstosupportnesting—thismeanstheenumerationneedstoberecursive.ThecodebelowshowstheArithmeticExpressionrecursiveenumerationbeingcreatedfor(5+4)*2:

1 letfive=ArithmeticExpression.number(5)

2 letfour=ArithmeticExpression.number(4)

3 letsum=ArithmeticExpression.addition(five,four)

4 letproduct=ArithmeticExpression.multiplication(sum,

ArithmeticExpression.number(2))

Arecursivefunctionisastraightforwardwaytoworkwithdatathathasarecursivestructure.Forexample,here’safunctionthatevaluatesanarithmeticexpression:

1 funcevaluate(_expression:ArithmeticExpression)->Int{

2 switchexpression{

3 caselet.number(value):

4 returnvalue

5 caselet.addition(left,right):

6 returnevaluate(left)+evaluate(right)

7 caselet.multiplication(left,right):

8 returnevaluate(left)*evaluate(right)

9 }

10 }

11

12 print(evaluate(product))

13 //Prints"18"

Page 217: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thisfunctionevaluatesaplainnumberbysimplyreturningtheassociatedvalue.Itevaluatesanadditionormultiplicationbyevaluatingtheexpressionontheleft-handside,evaluatingtheexpressionontheright-handside,andthenaddingthemormultiplyingthem.

Page 218: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

StructuresandClasses

Structuresandclassesaregeneral-purpose,flexibleconstructsthatbecomethebuildingblocksofyourprogram’scode.Youdefinepropertiesandmethodstoaddfunctionalitytoyourstructuresandclassesusingthesamesyntaxyouusetodefineconstants,variables,andfunctions.

Unlikeotherprogramminglanguages,Swiftdoesn’trequireyoutocreateseparateinterfaceandimplementationfilesforcustomstructuresandclasses.InSwift,youdefineastructureorclassinasinglefile,andtheexternalinterfacetothatclassorstructureisautomaticallymadeavailableforothercodetouse.

NOTE

Aninstanceofaclassistraditionallyknownasanobject.However,Swiftstructuresandclassesaremuchcloserinfunctionalitythaninotherlanguages,andmuchofthischapterdescribesfunctionalitythatappliestoinstancesofeitheraclassorastructuretype.Becauseofthis,themoregeneralterminstanceisused.

ComparingStructuresandClasses

StructuresandclassesinSwifthavemanythingsincommon.Bothcan:

Definepropertiestostorevalues

Definemethodstoprovidefunctionality

Definesubscriptstoprovideaccesstotheirvaluesusingsubscriptsyntax

Defineinitializerstosetuptheirinitialstate

Beextendedtoexpandtheirfunctionalitybeyondadefaultimplementation

Conformtoprotocolstoprovidestandardfunctionalityofacertainkind

Page 219: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Formoreinformation,seeProperties,Methods,Subscripts,Initialization,Extensions,andProtocols.

Classeshaveadditionalcapabilitiesthatstructuresdon’thave:

Inheritanceenablesoneclasstoinheritthecharacteristicsofanother.

Typecastingenablesyoutocheckandinterpretthetypeofaclassinstanceatruntime.

Deinitializersenableaninstanceofaclasstofreeupanyresourcesithasassigned.

Referencecountingallowsmorethanonereferencetoaclassinstance.

Formoreinformation,seeInheritance,TypeCasting,Deinitialization,andAutomaticReferenceCounting.

Theadditionalcapabilitiesthatclassessupportcomeatthecostofincreasedcomplexity.Asageneralguideline,preferstructuresbecausethey’reeasiertoreasonabout,anduseclasseswhenthey’reappropriateornecessary.Inpractice,thismeansmostofthecustomdatatypesyoudefinewillbestructuresandenumerations.Foramoredetailedcomparison,seeChoosingBetweenStructuresandClasses.

DefinitionSyntaxStructuresandclasseshaveasimilardefinitionsyntax.Youintroducestructureswiththestructkeywordandclasseswiththeclasskeyword.Bothplacetheirentiredefinitionwithinapairofbraces:

1 structSomeStructure{

2 //structuredefinitiongoeshere

3 }

4 classSomeClass{

5 //classdefinitiongoeshere

Page 220: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 }

NOTE

Wheneveryoudefineanewstructureorclass,youdefineanewSwifttype.GivetypesUpperCamelCasenames(suchasSomeStructureandSomeClasshere)tomatchthecapitalizationofstandardSwifttypes(suchasString,Int,andBool).GivepropertiesandmethodslowerCamelCasenames(suchasframeRateandincrementCount)todifferentiatethemfromtypenames.

Here’sanexampleofastructuredefinitionandaclassdefinition:

1 structResolution{

2 varwidth=0

3 varheight=0

4 }

5 classVideoMode{

6 varresolution=Resolution()

7 varinterlaced=false

8 varframeRate=0.0

9 varname:String?

10 }

TheexampleabovedefinesanewstructurecalledResolution,todescribeapixel-baseddisplayresolution.Thisstructurehastwostoredpropertiescalledwidthandheight.Storedpropertiesareconstantsorvariablesthatarebundledupandstoredaspartofthestructureorclass.ThesetwopropertiesareinferredtobeoftypeIntbysettingthemtoaninitialintegervalueof0.

TheexampleabovealsodefinesanewclasscalledVideoMode,todescribeaspecificvideomodeforvideodisplay.Thisclasshasfourvariablestoredproperties.Thefirst,resolution,isinitializedwithanewResolutionstructureinstance,whichinfersapropertytypeofResolution.Fortheotherthreeproperties,newVideoModeinstanceswillbeinitializedwithaninterlacedsettingoffalse(meaning“noninterlacedvideo”),aplaybackframerateof0.0,andanoptionalStringvaluecalledname.Thenamepropertyisautomatically

Page 221: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

givenadefaultvalueofnil,or“nonamevalue”,becauseit’sofanoptionaltype.

StructureandClassInstancesTheResolutionstructuredefinitionandtheVideoModeclassdefinitiononlydescribewhataResolutionorVideoModewilllooklike.Theythemselvesdon’tdescribeaspecificresolutionorvideomode.Todothat,youneedtocreateaninstanceofthestructureorclass.

Thesyntaxforcreatinginstancesisverysimilarforbothstructuresandclasses:

1 letsomeResolution=Resolution()

2 letsomeVideoMode=VideoMode()

Structuresandclassesbothuseinitializersyntaxfornewinstances.Thesimplestformofinitializersyntaxusesthetypenameoftheclassorstructurefollowedbyemptyparentheses,suchasResolution()orVideoMode().Thiscreatesanewinstanceoftheclassorstructure,withanypropertiesinitializedtotheirdefaultvalues.ClassandstructureinitializationisdescribedinmoredetailinInitialization.

AccessingPropertiesYoucanaccessthepropertiesofaninstanceusingdotsyntax.Indotsyntax,youwritethepropertynameimmediatelyaftertheinstancename,separatedbyaperiod(.),withoutanyspaces:

1 print("ThewidthofsomeResolutionis\(someResolution.width)")

2 //Prints"ThewidthofsomeResolutionis0"

Inthisexample,someResolution.widthreferstothewidthpropertyofsomeResolution,andreturnsitsdefaultinitialvalueof0.

Youcandrilldownintosubproperties,suchasthewidthpropertyintheresolutionpropertyofaVideoMode:

Page 222: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 print("ThewidthofsomeVideoModeis\

(someVideoMode.resolution.width)")

2 //Prints"ThewidthofsomeVideoModeis0"

Youcanalsousedotsyntaxtoassignanewvaluetoavariableproperty:

1 someVideoMode.resolution.width=1280

2 print("ThewidthofsomeVideoModeisnow\

(someVideoMode.resolution.width)")

3 //Prints"ThewidthofsomeVideoModeisnow1280"

MemberwiseInitializersforStructureTypesAllstructureshaveanautomaticallygeneratedmemberwiseinitializer,whichyoucanusetoinitializethememberpropertiesofnewstructureinstances.Initialvaluesforthepropertiesofthenewinstancecanbepassedtothememberwiseinitializerbyname:

letvga=Resolution(width:640,height:480)

Unlikestructures,classinstancesdon’treceiveadefaultmemberwiseinitializer.InitializersaredescribedinmoredetailinInitialization.

StructuresandEnumerationsAreValueTypes

Avaluetypeisatypewhosevalueiscopiedwhenit’sassignedtoavariableorconstant,orwhenit’spassedtoafunction.

You’veactuallybeenusingvaluetypesextensivelythroughoutthepreviouschapters.Infact,allofthebasictypesinSwift—integers,floating-pointnumbers,Booleans,strings,arraysanddictionaries—arevaluetypes,andareimplementedasstructuresbehindthescenes.

Page 223: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AllstructuresandenumerationsarevaluetypesinSwift.Thismeansthatanystructureandenumerationinstancesyoucreate—andanyvaluetypestheyhaveasproperties—arealwayscopiedwhentheyarepassedaroundinyourcode.

NOTE

Collectionsdefinedbythestandardlibrarylikearrays,dictionaries,andstringsuseanoptimizationtoreducetheperformancecostofcopying.Insteadofmakingacopyimmediately,thesecollectionssharethememorywheretheelementsarestoredbetweentheoriginalinstanceandanycopies.Ifoneofthecopiesofthecollectionismodified,theelementsarecopiedjustbeforethemodification.Thebehavioryouseeinyourcodeisalwaysasifacopytookplaceimmediately.

Considerthisexample,whichusestheResolutionstructurefromthepreviousexample:

1 lethd=Resolution(width:1920,height:1080)

2 varcinema=hd

ThisexampledeclaresaconstantcalledhdandsetsittoaResolutioninstanceinitializedwiththewidthandheightoffullHDvideo(1920pixelswideby1080pixelshigh).

Itthendeclaresavariablecalledcinemaandsetsittothecurrentvalueofhd.BecauseResolutionisastructure,acopyoftheexistinginstanceismade,andthisnewcopyisassignedtocinema.Eventhoughhdandcinemanowhavethesamewidthandheight,theyaretwocompletelydifferentinstancesbehindthescenes.

Next,thewidthpropertyofcinemaisamendedtobethewidthoftheslightlywider2Kstandardusedfordigitalcinemaprojection(2048pixelswideand1080pixelshigh):

cinema.width=2048

Checkingthewidthpropertyofcinemashowsthatithasindeedchangedtobe2048:

1 print("cinemaisnow\(cinema.width)pixelswide")

Page 224: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 //Prints"cinemaisnow2048pixelswide"

However,thewidthpropertyoftheoriginalhdinstancestillhastheoldvalueof1920:

1 print("hdisstill\(hd.width)pixelswide")

2 //Prints"hdisstill1920pixelswide"

Whencinemawasgiventhecurrentvalueofhd,thevaluesstoredinhdwerecopiedintothenewcinemainstance.Theendresultwastwocompletelyseparateinstancesthatcontainedthesamenumericvalues.However,becausetheyareseparateinstances,settingthewidthofcinemato2048doesn’taffectthewidthstoredinhd,asshowninthefigurebelow:

Thesamebehaviorappliestoenumerations:

1 enumCompassPoint{

2 casenorth,south,east,west

3 mutatingfuncturnNorth(){

4 self=.north

5 }

6 }

7 varcurrentDirection=CompassPoint.west

8 letrememberedDirection=currentDirection

9 currentDirection.turnNorth()

Page 225: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

10

11 print("Thecurrentdirectionis\(currentDirection)")

12 print("Theremembereddirectionis\(rememberedDirection)")

13 //Prints"Thecurrentdirectionisnorth"

14 //Prints"Theremembereddirectioniswest"

WhenrememberedDirectionisassignedthevalueofcurrentDirection,it’sactuallysettoacopyofthatvalue.ChangingthevalueofcurrentDirectionthereafterdoesn’taffectthecopyoftheoriginalvaluethatwasstoredinrememberedDirection.

ClassesAreReferenceTypes

Unlikevaluetypes,referencetypesarenotcopiedwhentheyareassignedtoavariableorconstant,orwhentheyarepassedtoafunction.Ratherthanacopy,areferencetothesameexistinginstanceisused.

Here’sanexample,usingtheVideoModeclassdefinedabove:

1 lettenEighty=VideoMode()

2 tenEighty.resolution=hd

3 tenEighty.interlaced=true

4 tenEighty.name="1080i"

5 tenEighty.frameRate=25.0

ThisexampledeclaresanewconstantcalledtenEightyandsetsittorefertoanewinstanceoftheVideoModeclass.ThevideomodeisassignedacopyoftheHDresolutionof1920by1080frombefore.It’ssettobeinterlaced,itsnameissetto"1080i",anditsframerateissetto25.0framespersecond.

Next,tenEightyisassignedtoanewconstant,calledalsoTenEighty,andtheframerateofalsoTenEightyismodified:

Page 226: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letalsoTenEighty=tenEighty

2 alsoTenEighty.frameRate=30.0

Becauseclassesarereferencetypes,tenEightyandalsoTenEightyactuallybothrefertothesameVideoModeinstance.Effectively,theyarejusttwodifferentnamesforthesamesingleinstance,asshowninthefigurebelow:

CheckingtheframeRatepropertyoftenEightyshowsthatitcorrectlyreportsthenewframerateof30.0fromtheunderlyingVideoModeinstance:

1 print("TheframeRatepropertyoftenEightyisnow\

(tenEighty.frameRate)")

2 //Prints"TheframeRatepropertyoftenEightyisnow30.0"

Thisexamplealsoshowshowreferencetypescanbehardertoreasonabout.IftenEightyandalsoTenEightywerefarapartinyourprogram’scode,itcouldbedifficulttofindallthewaysthatthevideomodeischanged.WhereveryouusetenEighty,youalsohavetothinkaboutthecodethatusesalsoTenEighty,andviceversa.Incontrast,valuetypesareeasiertoreasonaboutbecauseallofthecodethatinteractswiththesamevalueisclosetogetherinyoursourcefiles.

NotethattenEightyandalsoTenEightyaredeclaredasconstants,ratherthanvariables.However,youcanstillchangetenEighty.frameRateandalsoTenEighty.frameRatebecausethevaluesofthetenEightyandalsoTenEightyconstantsthemselvesdon’tactuallychange.tenEightyandalsoTenEightythemselvesdon’t“store”theVideoModeinstance—instead,theybothrefertoaVideoModeinstancebehindthescenes.It’stheframeRatepropertyoftheunderlyingVideoModethatischanged,notthevaluesoftheconstantreferencestothatVideoMode.

Page 227: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

IdentityOperatorsBecauseclassesarereferencetypes,it’spossibleformultipleconstantsandvariablestorefertothesamesingleinstanceofaclassbehindthescenes.(Thesameisn’ttrueforstructuresandenumerations,becausetheyarealwayscopiedwhentheyareassignedtoaconstantorvariable,orpassedtoafunction.)

Itcansometimesbeusefultofindoutwhethertwoconstantsorvariablesrefertoexactlythesameinstanceofaclass.Toenablethis,Swiftprovidestwoidentityoperators:

Identicalto(===)

Notidenticalto(!==)

Usetheseoperatorstocheckwhethertwoconstantsorvariablesrefertothesamesingleinstance:

1 iftenEighty===alsoTenEighty{

2 print("tenEightyandalsoTenEightyrefertothesame

VideoModeinstance.")

3 }

4 //Prints"tenEightyandalsoTenEightyrefertothesame

VideoModeinstance."

Notethatidenticalto(representedbythreeequalssigns,or===)doesn’tmeanthesamethingasequalto(representedbytwoequalssigns,or==).Identicaltomeansthattwoconstantsorvariablesofclasstyperefertoexactlythesameclassinstance.Equaltomeansthattwoinstancesareconsideredequalorequivalentinvalue,forsomeappropriatemeaningofequal,asdefinedbythetype’sdesigner.

Whenyoudefineyourowncustomstructuresandclasses,it’syourresponsibilitytodecidewhatqualifiesastwoinstancesbeingequal.Theprocessofdefiningyourownimplementationsofthe==and!=operatorsisdescribedinEquivalenceOperators.

Page 228: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

PointersIfyouhaveexperiencewithC,C++,orObjective-C,youmayknowthattheselanguagesusepointerstorefertoaddressesinmemory.ASwiftconstantorvariablethatreferstoaninstanceofsomereferencetypeissimilartoapointerinC,butisn’tadirectpointertoanaddressinmemory,anddoesn’trequireyoutowriteanasterisk(*)toindicatethatyouarecreatingareference.Instead,thesereferencesaredefinedlikeanyotherconstantorvariableinSwift.Thestandardlibraryprovidespointerandbuffertypesthatyoucanuseifyouneedtointeractwithpointersdirectly—seeManualMemoryManagement.

Page 229: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Properties

Propertiesassociatevalueswithaparticularclass,structure,orenumeration.Storedpropertiesstoreconstantandvariablevaluesaspartofaninstance,whereascomputedpropertiescalculate(ratherthanstore)avalue.Computedpropertiesareprovidedbyclasses,structures,andenumerations.Storedpropertiesareprovidedonlybyclassesandstructures.

Storedandcomputedpropertiesareusuallyassociatedwithinstancesofaparticulartype.However,propertiescanalsobeassociatedwiththetypeitself.Suchpropertiesareknownastypeproperties.

Inaddition,youcandefinepropertyobserverstomonitorchangesinaproperty’svalue,whichyoucanrespondtowithcustomactions.Propertyobserverscanbeaddedtostoredpropertiesyoudefineyourself,andalsotopropertiesthatasubclassinheritsfromitssuperclass.

Youcanalsouseapropertywrappertoreusecodeinthegetterandsetterofmultipleproperties.

StoredProperties

Initssimplestform,astoredpropertyisaconstantorvariablethatisstoredaspartofaninstanceofaparticularclassorstructure.Storedpropertiescanbeeithervariablestoredproperties(introducedbythevarkeyword)orconstantstoredproperties(introducedbytheletkeyword).

Youcanprovideadefaultvalueforastoredpropertyaspartofitsdefinition,asdescribedinDefaultPropertyValues.Youcanalsosetandmodifytheinitialvalueforastoredpropertyduringinitialization.Thisistrueevenforconstantstoredproperties,asdescribedinAssigningConstantPropertiesDuringInitialization.

TheexamplebelowdefinesastructurecalledFixedLengthRange,whichdescribes

Page 230: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

arangeofintegerswhoserangelengthcannotbechangedafteritiscreated:

1 structFixedLengthRange{

2 varfirstValue:Int

3 letlength:Int

4 }

5 varrangeOfThreeItems=FixedLengthRange(firstValue:0,length:

3)

6 //therangerepresentsintegervalues0,1,and2

7 rangeOfThreeItems.firstValue=6

8 //therangenowrepresentsintegervalues6,7,and8

InstancesofFixedLengthRangehaveavariablestoredpropertycalledfirstValueandaconstantstoredpropertycalledlength.Intheexampleabove,lengthisinitializedwhenthenewrangeiscreatedandcannotbechangedthereafter,becauseitisaconstantproperty.

StoredPropertiesofConstantStructureInstancesIfyoucreateaninstanceofastructureandassignthatinstancetoaconstant,youcannotmodifytheinstance’sproperties,eveniftheyweredeclaredasvariableproperties:

1 letrangeOfFourItems=FixedLengthRange(firstValue:0,length:

4)

2 //thisrangerepresentsintegervalues0,1,2,and3

3 rangeOfFourItems.firstValue=6

4 //thiswillreportanerror,eventhoughfirstValueisa

variableproperty

BecauserangeOfFourItemsisdeclaredasaconstant(withtheletkeyword),itisnotpossibletochangeitsfirstValueproperty,eventhoughfirstValueisa

Page 231: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

variableproperty.

Thisbehaviorisduetostructuresbeingvaluetypes.Whenaninstanceofavaluetypeismarkedasaconstant,soareallofitsproperties.

Thesameisnottrueforclasses,whicharereferencetypes.Ifyouassignaninstanceofareferencetypetoaconstant,youcanstillchangethatinstance’svariableproperties.

LazyStoredPropertiesAlazystoredpropertyisapropertywhoseinitialvalueisnotcalculateduntilthefirsttimeitisused.Youindicatealazystoredpropertybywritingthelazymodifierbeforeitsdeclaration.

NOTE

Youmustalwaysdeclarealazypropertyasavariable(withthevarkeyword),becauseitsinitialvaluemightnotberetrieveduntilafterinstanceinitializationcompletes.Constantpropertiesmustalwayshaveavaluebeforeinitializationcompletes,andthereforecannotbedeclaredaslazy.

Lazypropertiesareusefulwhentheinitialvalueforapropertyisdependentonoutsidefactorswhosevaluesarenotknownuntilafteraninstance’sinitializationiscomplete.Lazypropertiesarealsousefulwhentheinitialvalueforapropertyrequirescomplexorcomputationallyexpensivesetupthatshouldnotbeperformedunlessoruntilitisneeded.

Theexamplebelowusesalazystoredpropertytoavoidunnecessaryinitializationofacomplexclass.ThisexampledefinestwoclassescalledDataImporterandDataManager,neitherofwhichisshowninfull:

1 classDataImporter{

2 /*

3 DataImporterisaclasstoimportdatafromanexternal

file.

4 Theclassisassumedtotakeanontrivialamountoftimeto

Page 232: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

initialize.

5 */

6 varfilename="data.txt"

7 //theDataImporterclasswouldprovidedataimporting

functionalityhere

8 }

9

10 classDataManager{

11 lazyvarimporter=DataImporter()

12 vardata=[String]()

13 //theDataManagerclasswouldprovidedatamanagement

functionalityhere

14 }

15

16 letmanager=DataManager()

17 manager.data.append("Somedata")

18 manager.data.append("Somemoredata")

19 //theDataImporterinstancefortheimporterpropertyhasnot

yetbeencreated

TheDataManagerclasshasastoredpropertycalleddata,whichisinitializedwithanew,emptyarrayofStringvalues.Althoughtherestofitsfunctionalityisnotshown,thepurposeofthisDataManagerclassistomanageandprovideaccesstothisarrayofStringdata.

PartofthefunctionalityoftheDataManagerclassistheabilitytoimportdatafromafile.ThisfunctionalityisprovidedbytheDataImporterclass,whichisassumedtotakeanontrivialamountoftimetoinitialize.ThismightbebecauseaDataImporterinstanceneedstoopenafileandreaditscontentsintomemorywhentheDataImporterinstanceisinitialized.

ItispossibleforaDataManagerinstancetomanageitsdatawithouteverimportingdatafromafile,sothereisnoneedtocreateanewDataImporter

Page 233: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

instancewhentheDataManageritselfiscreated.Instead,itmakesmoresensetocreatetheDataImporterinstanceifandwhenitisfirstused.

Becauseitismarkedwiththelazymodifier,theDataImporterinstancefortheimporterpropertyisonlycreatedwhentheimporterpropertyisfirstaccessed,suchaswhenitsfilenamepropertyisqueried:

1 print(manager.importer.filename)

2 //theDataImporterinstancefortheimporterpropertyhasnow

beencreated

3 //Prints"data.txt"

NOTE

Ifapropertymarkedwiththelazymodifierisaccessedbymultiplethreadssimultaneouslyandthepropertyhasnotyetbeeninitialized,thereisnoguaranteethatthepropertywillbeinitializedonlyonce.

StoredPropertiesandInstanceVariablesIfyouhaveexperiencewithObjective-C,youmayknowthatitprovidestwowaystostorevaluesandreferencesaspartofaclassinstance.Inadditiontoproperties,youcanuseinstancevariablesasabackingstoreforthevaluesstoredinaproperty.

Swiftunifiestheseconceptsintoasinglepropertydeclaration.ASwiftpropertydoesnothaveacorrespondinginstancevariable,andthebackingstoreforapropertyisnotaccesseddirectly.Thisapproachavoidsconfusionabouthowthevalueisaccessedindifferentcontextsandsimplifiestheproperty’sdeclarationintoasingle,definitivestatement.Allinformationabouttheproperty—includingitsname,type,andmemorymanagementcharacteristics—isdefinedinasinglelocationaspartofthetype’sdefinition.

ComputedProperties

Page 234: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Inadditiontostoredproperties,classes,structures,andenumerationscandefinecomputedproperties,whichdonotactuallystoreavalue.Instead,theyprovideagetterandanoptionalsettertoretrieveandsetotherpropertiesandvaluesindirectly.

1 structPoint{

2 varx=0.0,y=0.0

3 }

4 structSize{

5 varwidth=0.0,height=0.0

6 }

7 structRect{

8 varorigin=Point()

9 varsize=Size()

10 varcenter:Point{

11 get{

12 letcenterX=origin.x+(size.width/2)

13 letcenterY=origin.y+(size.height/2)

14 returnPoint(x:centerX,y:centerY)

15 }

16 set(newCenter){

17 origin.x=newCenter.x-(size.width/2)

18 origin.y=newCenter.y-(size.height/2)

19 }

20 }

21 }

22 varsquare=Rect(origin:Point(x:0.0,y:0.0),

23 size:Size(width:10.0,height:10.0))

24 letinitialSquareCenter=square.center

25 square.center=Point(x:15.0,y:15.0)

26 print("square.originisnowat(\(square.origin.x),\

Page 235: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

(square.origin.y))")

27 //Prints"square.originisnowat(10.0,10.0)"

Thisexampledefinesthreestructuresforworkingwithgeometricshapes:

Pointencapsulatesthex-andy-coordinateofapoint.

Sizeencapsulatesawidthandaheight.

Rectdefinesarectanglebyanoriginpointandasize.

TheRectstructurealsoprovidesacomputedpropertycalledcenter.ThecurrentcenterpositionofaRectcanalwaysbedeterminedfromitsoriginandsize,andsoyoudon’tneedtostorethecenterpointasanexplicitPointvalue.Instead,Rectdefinesacustomgetterandsetterforacomputedvariablecalledcenter,toenableyoutoworkwiththerectangle’scenterasifitwerearealstoredproperty.

TheexampleabovecreatesanewRectvariablecalledsquare.Thesquarevariableisinitializedwithanoriginpointof(0,0),andawidthandheightof10.Thissquareisrepresentedbythebluesquareinthediagrambelow.

Thesquarevariable’scenterpropertyisthenaccessedthroughdotsyntax(square.center),whichcausesthegetterforcentertobecalled,toretrievethecurrentpropertyvalue.Ratherthanreturninganexistingvalue,thegetteractuallycalculatesandreturnsanewPointtorepresentthecenterofthesquare.Ascanbeseenabove,thegettercorrectlyreturnsacenterpointof(5,5).

Thecenterpropertyisthensettoanewvalueof(15,15),whichmovesthesquareupandtotheright,tothenewpositionshownbytheorangesquareinthediagrambelow.Settingthecenterpropertycallsthesetterforcenter,whichmodifiesthexandyvaluesofthestoredoriginproperty,andmovesthesquaretoitsnewposition.

Page 236: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ShorthandSetterDeclarationIfacomputedproperty’ssetterdoesn’tdefineanameforthenewvaluetobeset,adefaultnameofnewValueisused.Here’sanalternativeversionoftheRectstructurethattakesadvantageofthisshorthandnotation:

1 structAlternativeRect{

2 varorigin=Point()

3 varsize=Size()

4 varcenter:Point{

5 get{

6 letcenterX=origin.x+(size.width/2)

7 letcenterY=origin.y+(size.height/2)

8 returnPoint(x:centerX,y:centerY)

9 }

10 set{

Page 237: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

11 origin.x=newValue.x-(size.width/2)

12 origin.y=newValue.y-(size.height/2)

13 }

14 }

15 }

ShorthandGetterDeclarationIftheentirebodyofagetterisasingleexpression,thegetterimplicitlyreturnsthatexpression.Here’sananotherversionoftheRectstructurethattakesadvantageofthisshorthandnotationandtheshorthandnotationforsetters:

1 structCompactRect{

2 varorigin=Point()

3 varsize=Size()

4 varcenter:Point{

5 get{

6 Point(x:origin.x+(size.width/2),

7 y:origin.y+(size.height/2))

8 }

9 set{

10 origin.x=newValue.x-(size.width/2)

11 origin.y=newValue.y-(size.height/2)

12 }

13 }

14 }

Omittingthereturnfromagetterfollowsthesamerulesasomittingreturnfromafunction,asdescribedinFunctionsWithanImplicitReturn.

Page 238: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Read-OnlyComputedPropertiesAcomputedpropertywithagetterbutnosetterisknownasaread-onlycomputedproperty.Aread-onlycomputedpropertyalwaysreturnsavalue,andcanbeaccessedthroughdotsyntax,butcannotbesettoadifferentvalue.

NOTE

Youmustdeclarecomputedproperties—includingread-onlycomputedproperties—asvariablepropertieswiththevarkeyword,becausetheirvalueisnotfixed.Theletkeywordisonlyusedforconstantproperties,toindicatethattheirvaluescannotbechangedoncetheyaresetaspartofinstanceinitialization.

Youcansimplifythedeclarationofaread-onlycomputedpropertybyremovingthegetkeywordanditsbraces:

1 structCuboid{

2 varwidth=0.0,height=0.0,depth=0.0

3 varvolume:Double{

4 returnwidth*height*depth

5 }

6 }

7 letfourByFiveByTwo=Cuboid(width:4.0,height:5.0,depth:

2.0)

8 print("thevolumeoffourByFiveByTwois\

(fourByFiveByTwo.volume)")

9 //Prints"thevolumeoffourByFiveByTwois40.0"

ThisexampledefinesanewstructurecalledCuboid,whichrepresentsa3Drectangularboxwithwidth,height,anddepthproperties.Thisstructurealsohasaread-onlycomputedpropertycalledvolume,whichcalculatesandreturnsthecurrentvolumeofthecuboid.Itdoesn’tmakesenseforvolumetobesettable,becauseitwouldbeambiguousastowhichvaluesofwidth,height,anddepthshouldbeusedforaparticularvolumevalue.Nonetheless,itisusefulforaCuboidtoprovidearead-onlycomputedpropertytoenableexternaluserstodiscoveritscurrentcalculatedvolume.

Page 239: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

PropertyObservers

Propertyobserversobserveandrespondtochangesinaproperty’svalue.Propertyobserversarecalledeverytimeaproperty’svalueisset,evenifthenewvalueisthesameastheproperty’scurrentvalue.

Youcanaddpropertyobserverstoanystoredpropertiesyoudefine,exceptforlazystoredproperties.Youcanalsoaddpropertyobserverstoanyinheritedproperty(whetherstoredorcomputed)byoverridingthepropertywithinasubclass.Youdon’tneedtodefinepropertyobserversfornonoverriddencomputedproperties,becauseyoucanobserveandrespondtochangestotheirvalueinthecomputedproperty’ssetter.PropertyoverridingisdescribedinOverriding.

Youhavetheoptiontodefineeitherorbothoftheseobserversonaproperty:

willSetiscalledjustbeforethevalueisstored.

didSetiscalledimmediatelyafterthenewvalueisstored.

IfyouimplementawillSetobserver,it’spassedthenewpropertyvalueasaconstantparameter.YoucanspecifyanameforthisparameteraspartofyourwillSetimplementation.Ifyoudon’twritetheparameternameandparentheseswithinyourimplementation,theparameterismadeavailablewithadefaultparameternameofnewValue.

Similarly,ifyouimplementadidSetobserver,it’spassedaconstantparametercontainingtheoldpropertyvalue.YoucannametheparameterorusethedefaultparameternameofoldValue.IfyouassignavaluetoapropertywithinitsowndidSetobserver,thenewvaluethatyouassignreplacestheonethatwasjustset.

NOTE

ThewillSetanddidSetobserversofsuperclasspropertiesarecalledwhenapropertyissetinasubclassinitializer,afterthesuperclassinitializerhasbeencalled.Theyarenotcalledwhileaclassissettingitsownproperties,beforethesuperclassinitializerhasbeencalled.

Formoreinformationaboutinitializerdelegation,seeInitializerDelegationforValueTypesandInitializerDelegationforClassTypes.

Page 240: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Here’sanexampleofwillSetanddidSetinaction.TheexamplebelowdefinesanewclasscalledStepCounter,whichtracksthetotalnumberofstepsthatapersontakeswhilewalking.Thisclassmightbeusedwithinputdatafromapedometerorotherstepcountertokeeptrackofaperson’sexerciseduringtheirdailyroutine.

1 classStepCounter{

2 vartotalSteps:Int=0{

3 willSet(newTotalSteps){

4 print("AbouttosettotalStepsto\

(newTotalSteps)")

5 }

6 didSet{

7 iftotalSteps>oldValue{

8 print("Added\(totalSteps-oldValue)steps")

9 }

10 }

11 }

12 }

13 letstepCounter=StepCounter()

14 stepCounter.totalSteps=200

15 //AbouttosettotalStepsto200

16 //Added200steps

17 stepCounter.totalSteps=360

18 //AbouttosettotalStepsto360

19 //Added160steps

20 stepCounter.totalSteps=896

21 //AbouttosettotalStepsto896

22 //Added536steps

TheStepCounterclassdeclaresatotalStepspropertyoftypeInt.Thisisa

Page 241: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

storedpropertywithwillSetanddidSetobservers.

ThewillSetanddidSetobserversfortotalStepsarecalledwheneverthepropertyisassignedanewvalue.Thisistrueevenifthenewvalueisthesameasthecurrentvalue.

Thisexample’swillSetobserverusesacustomparameternameofnewTotalStepsfortheupcomingnewvalue.Inthisexample,itsimplyprintsoutthevaluethatisabouttobeset.

ThedidSetobserveriscalledafterthevalueoftotalStepsisupdated.ItcomparesthenewvalueoftotalStepsagainsttheoldvalue.Ifthetotalnumberofstepshasincreased,amessageisprintedtoindicatehowmanynewstepshavebeentaken.ThedidSetobserverdoesnotprovideacustomparameternamefortheoldvalue,andthedefaultnameofoldValueisusedinstead.

NOTE

Ifyoupassapropertythathasobserverstoafunctionasanin-outparameter,thewillSetanddidSetobserversarealwayscalled.Thisisbecauseofthecopy-incopy-outmemorymodelforin-outparameters:Thevalueisalwayswrittenbacktothepropertyattheendofthefunction.Foradetaileddiscussionofthebehaviorofin-outparameters,seeIn-OutParameters.

PropertyWrappers

Apropertywrapperaddsalayerofseparationbetweencodethatmanageshowapropertyisstoredandthecodethatdefinesaproperty.Forexample,ifyouhavepropertiesthatprovidethread-safetychecksorstoretheirunderlyingdatainadatabase,youhavetowritethatcodeoneveryproperty.Whenyouuseapropertywrapper,youwritethemanagementcodeoncewhenyoudefinethewrapper,andthenreusethatmanagementcodebyapplyingittomultipleproperties.

Todefineapropertywrapper,youmakeastructure,enumeration,orclassthatdefinesawrappedValueproperty.Inthecodebelow,theTwelveOrLessstructureensuresthatthevalueitwrapsalwayscontainsanumberlessthanorequalto12.

Page 242: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Ifyouaskittostorealargernumber,itstores12instead.

1 @propertyWrapper

2 structTwelveOrLess{

3 privatevarnumber=0

4 varwrappedValue:Int{

5 get{returnnumber}

6 set{number=min(newValue,12)}

7 }

8 }

Thesetterensuresthatnewvaluesarelessthan12,andthegetterreturnsthestoredvalue.

NOTE

Thedeclarationfornumberintheexampleabovemarksthevariableasprivate,whichensuresnumberisusedonlyintheimplementationofTwelveOrLess.Codethat’swrittenanywhereelseaccessesthevalueusingthegetterandsetterforwrappedValue,andcan’tusenumberdirectly.Forinformationaboutprivate,seeAccessControl.

Youapplyawrappertoapropertybywritingthewrapper’snamebeforethepropertyasanattribute.Here’sastructurethatstoresasmallrectangle,usingthesame(ratherarbitrary)definitionof“small”that’simplementedbytheTwelveOrLesspropertywrapper:

1 structSmallRectangle{

2 @TwelveOrLessvarheight:Int

3 @TwelveOrLessvarwidth:Int

4 }

5

6 varrectangle=SmallRectangle()

7 print(rectangle.height)

8 //Prints"0"

Page 243: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9

10 rectangle.height=10

11 print(rectangle.height)

12 //Prints"10"

13

14 rectangle.height=24

15 print(rectangle.height)

16 //Prints"12"

TheheightandwidthpropertiesgettheirinitialvaluesfromthedefinitionofTwelveOrLess,whichsetsTwelveOrLess.numbertozero.Storingthenumber10intorectangle.heightsucceedsbecauseit’sasmallnumber.Tryingtostore24actuallystoresavalueof12instead,because24istoolargeforthepropertysetter’srule.

Whenyouapplyawrappertoaproperty,thecompilersynthesizescodethatprovidesstorageforthewrapperandcodethatprovidesaccesstothepropertythroughthewrapper.(Thepropertywrapperisresponsibleforstoringthewrappedvalue,sothere’snosynthesizedcodeforthat.)Youcouldwritecodethatusesthebehaviorofapropertywrapper,withouttakingadvantageofthespecialattributesyntax.Forexample,here’saversionofSmallRectanglefromthepreviouscodelistingthatwrapsitspropertiesintheTwelveOrLessstructureexplicitly,insteadofwriting@TwelveOrLessasanattribute:

1 structSmallRectangle{

2 privatevar_height=TwelveOrLess()

3 privatevar_width=TwelveOrLess()

4 varheight:Int{

5 get{return_height.wrappedValue}

6 set{_height.wrappedValue=newValue}

7 }

8 varwidth:Int{

9 get{return_width.wrappedValue}

Page 244: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

10 set{_width.wrappedValue=newValue}

11 }

12 }

The_heightand_widthpropertiesstoreaninstanceofthepropertywrapper,TwelveOrLess.ThegetterandsetterforheightandwidthwrapaccesstothewrappedValueproperty.

SettingInitialValuesforWrappedPropertiesThecodeintheexamplesabovesetstheinitialvalueforthewrappedpropertybygivingnumberaninitialvalueinthedefinitionofTwelveOrLess.Codethatusesthispropertywrapper,can’tspecifyadifferentinitialvalueforapropertythat’swrappedbyTwelveOrLess—forexample,thedefinitionofSmallRectanglecan’tgiveheightorwidthinitialvalues.Tosupportsettinganinitialvalueorothercustomization,thepropertywrapperneedstoaddaninitializer.Here’sanexpandedversionofTwelveOrLesscalledSmallNumberthatdefinesinitializersthatsetthewrappedandmaximumvalue:

1 @propertyWrapper

2 structSmallNumber{

3 privatevarmaximum:Int

4 privatevarnumber:Int

5

6 varwrappedValue:Int{

7 get{returnnumber}

8 set{number=min(newValue,maximum)}

9 }

10

11 init(){

12 maximum=12

13 number=0

Page 245: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

14 }

15 init(wrappedValue:Int){

16 maximum=12

17 number=min(wrappedValue,maximum)

18 }

19 init(wrappedValue:Int,maximum:Int){

20 self.maximum=maximum

21 number=min(wrappedValue,maximum)

22 }

23 }

ThedefinitionofSmallNumberincludesthreeinitializers—init(),init(wrappedValue:),andinit(wrappedValue:maximum:)—whichtheexamplesbelowusetosetthewrappedvalueandthemaximumvalue.Forinformationaboutinitializationandinitializersyntax,seeInitialization.

Whenyouapplyawrappertoapropertyandyoudon’tspecifyaninitialvalue,Swiftusestheinit()initializertosetupthewrapper.Forexample:

1 structZeroRectangle{

2 @SmallNumbervarheight:Int

3 @SmallNumbervarwidth:Int

4 }

5

6 varzeroRectangle=ZeroRectangle()

7 print(zeroRectangle.height,zeroRectangle.width)

8 //Prints"00"

TheinstancesofSmallNumberthatwrapheightandwidtharecreatedbycallingSmallNumber().Thecodeinsidethatinitializersetstheinitialwrappedvalueandtheinitialmaximumvalue,usingthedefaultvaluesofzeroand12.Thepropertywrapperstillprovidesalloftheinitialvalues,liketheearlierexamplethatusedTwelveOrLessinSmallRectangle.Unlikethatexample,SmallNumberalso

Page 246: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

supportswritingthoseinitialvaluesaspartofdeclaringtheproperty.

Whenyouspecifyaninitialvaluefortheproperty,Swiftusestheinit(wrappedValue:)initializertosetupthewrapper.Forexample:

1 structUnitRectangle{

2 @SmallNumbervarheight:Int=1

3 @SmallNumbervarwidth:Int=1

4 }

5

6 varunitRectangle=UnitRectangle()

7 print(unitRectangle.height,unitRectangle.width)

8 //Prints"11"

Whenyouwrite=1onapropertywithawrapper,that’stranslatedintoacalltotheinit(wrappedValue:)initializer.TheinstancesofSmallNumberthatwrapheightandwidtharecreatedbycallingSmallNumber(wrappedValue:1).Theinitializerusesthewrappedvaluethat’sspecifiedhere,anditusesthedefaultmaximumvalueof12.

Whenyouwriteargumentsinparenthesesafterthecustomattribute,Swiftusestheinitializerthatacceptsthoseargumentstosetupthewrapper.Forexample,ifyouprovideaninitialvalueandamaximumvalue,Swiftusestheinit(wrappedValue:maximum:)initializer:

1 structNarrowRectangle{

2 @SmallNumber(wrappedValue:2,maximum:5)varheight:Int

3 @SmallNumber(wrappedValue:3,maximum:4)varwidth:Int

4 }

5

6 varnarrowRectangle=NarrowRectangle()

7 print(narrowRectangle.height,narrowRectangle.width)

8 //Prints"23"

Page 247: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9

10 narrowRectangle.height=100

11 narrowRectangle.width=100

12 print(narrowRectangle.height,narrowRectangle.width)

13 //Prints"54"

TheinstanceofSmallNumberthatwrapsheightiscreatedbycallingSmallNumber(wrappedValue:2,maximum:5),andtheinstancethatwrapswidthiscreatedbycallingSmallNumber(wrappedValue:3,maximum:4).

Byincludingargumentstothepropertywrapper,youcansetuptheinitialstateinthewrapperorpassotheroptionstothewrapperwhenit’screated.Thissyntaxisthemostgeneralwaytouseapropertywrapper.Youcanprovidewhateverargumentsyouneedtotheattribute,andthey’repassedtotheinitializer.

Whenyouincludepropertywrapperarguments,youcanalsospecifyaninitialvalueusingassignment.SwifttreatstheassignmentlikeawrappedValueargumentandusestheinitializerthatacceptstheargumentsyouinclude.Forexample:

1 structMixedRectangle{

2 @SmallNumbervarheight:Int=1

3 @SmallNumber(maximum:9)varwidth:Int=2

4 }

5

6 varmixedRectangle=MixedRectangle()

7 print(mixedRectangle.height)

8 //Prints"1"

9

10 mixedRectangle.height=20

11 print(mixedRectangle.height)

12 //Prints"12"

Page 248: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheinstanceofSmallNumberthatwrapsheightiscreatedbycallingSmallNumber(wrappedValue:1),whichusesthedefaultmaximumvalueof12.TheinstancethatwrapswidthiscreatedbycallingSmallNumber(wrappedValue:2,maximum:9).

ProjectingaValueFromaPropertyWrapperInadditiontothewrappedvalue,apropertywrappercanexposeadditionalfunctionalitybydefiningaprojectedvalue—forexample,apropertywrapperthatmanagesaccesstoadatabasecanexposeaflushDatabaseConnection()methodonitsprojectedvalue.Thenameoftheprojectedvalueisthesameasthewrappedvalue,exceptitbeginswithadollarsign($).Becauseyourcodecan’tdefinepropertiesthatstartwith$theprojectedvalueneverinterfereswithpropertiesyoudefine.

IntheSmallNumberexampleabove,ifyoutrytosetthepropertytoanumberthat’stoolarge,thepropertywrapperadjuststhenumberbeforestoringit.ThecodebelowaddsaprojectedValuepropertytotheSmallNumberstructuretokeeptrackofwhetherthepropertywrapperadjustedthenewvalueforthepropertybeforestoringthatnewvalue.

1 @propertyWrapper

2 structSmallNumber{

3 privatevarnumber=0

4 varprojectedValue=false

5 varwrappedValue:Int{

6 get{returnnumber}

7 set{

8 ifnewValue>12{

9 number=12

10 projectedValue=true

11 }else{

12 number=newValue

Page 249: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

13 projectedValue=false

14 }

15 }

16 }

17 }

18 structSomeStructure{

19 @SmallNumbervarsomeNumber:Int

20 }

21 varsomeStructure=SomeStructure()

22

23 someStructure.someNumber=4

24 print(someStructure.$someNumber)

25 //Prints"false"

26

27 someStructure.someNumber=55

28 print(someStructure.$someNumber)

29 //Prints"true"

Writings.$someNumberaccessesthewrapper’sprojectedvalue.Afterstoringasmallnumberlikefour,thevalueofs.$someNumberisfalse.However,theprojectedvalueistrueaftertryingtostoreanumberthat’stoolarge,like55.

Apropertywrappercanreturnavalueofanytypeasitsprojectedvalue.Inthisexample,thepropertywrapperexposesonlyonepieceofinformation—whetherthenumberwasadjusted—soitexposesthatBooleanvalueasitsprojectedvalue.Awrapperthatneedstoexposemoreinformationcanreturnaninstanceofsomeotherdatatype,oritcanreturnselftoexposetheinstanceofthewrapperasitsprojectedvalue.

Whenyouaccessaprojectedvaluefromcodethat’spartofthetype,likeapropertygetteroraninstancemethod,youcanomitself.beforethepropertyname,justlikeaccessingotherproperties.Thecodeinthefollowingexamplereferstotheprojectedvalueofthewrapperaroundheightandwidthas$height

Page 250: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

and$width:

1 enumSize{

2 casesmall,large

3 }

4

5 structSizedRectangle{

6 @SmallNumbervarheight:Int

7 @SmallNumbervarwidth:Int

8

9 mutatingfuncresize(tosize:Size)->Bool{

10 switchsize{

11 case.small:

12 height=10

13 width=20

14 case.large:

15 height=100

16 width=100

17 }

18 return$height||$width

19 }

20 }

Becausepropertywrappersyntaxisjustsyntacticsugarforapropertywithagetterandasetter,accessingheightandwidthbehavesthesameasaccessinganyotherproperty.Forexample,thecodeinresize(to:)accessesheightandwidthusingtheirpropertywrapper.Ifyoucallresize(to:.large),theswitchcasefor.largesetstherectangle’sheightandwidthto100.Thewrapperpreventsthevalueofthosepropertiesfrombeinglargerthan12,anditsetstheprojectedvaluetotrue,torecordthefactthatitadjustedtheirvalues.Attheendofresize(to:),thereturnstatementchecks$heightand$widthtodeterminewhetherthepropertywrapperadjustedeitherheightorwidth.

Page 251: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GlobalandLocalVariables

Thecapabilitiesdescribedaboveforcomputingandobservingpropertiesarealsoavailabletoglobalvariablesandlocalvariables.Globalvariablesarevariablesthataredefinedoutsideofanyfunction,method,closure,ortypecontext.Localvariablesarevariablesthataredefinedwithinafunction,method,orclosurecontext.

Theglobalandlocalvariablesyouhaveencounteredinpreviouschaptershaveallbeenstoredvariables.Storedvariables,likestoredproperties,providestorageforavalueofacertaintypeandallowthatvaluetobesetandretrieved.

However,youcanalsodefinecomputedvariablesanddefineobserversforstoredvariables,ineitheraglobalorlocalscope.Computedvariablescalculatetheirvalue,ratherthanstoringit,andtheyarewritteninthesamewayascomputedproperties.

NOTE

Globalconstantsandvariablesarealwayscomputedlazily,inasimilarmannertoLazyStoredProperties.Unlikelazystoredproperties,globalconstantsandvariablesdonotneedtobemarkedwiththelazymodifier.

Localconstantsandvariablesarenevercomputedlazily.

TypeProperties

Instancepropertiesarepropertiesthatbelongtoaninstanceofaparticulartype.Everytimeyoucreateanewinstanceofthattype,ithasitsownsetofpropertyvalues,separatefromanyotherinstance.

Youcanalsodefinepropertiesthatbelongtothetypeitself,nottoanyoneinstanceofthattype.Therewillonlyeverbeonecopyoftheseproperties,nomatterhowmanyinstancesofthattypeyoucreate.Thesekindsofpropertiesarecalledtypeproperties.

Typepropertiesareusefulfordefiningvaluesthatareuniversaltoallinstances

Page 252: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ofaparticulartype,suchasaconstantpropertythatallinstancescanuse(likeastaticconstantinC),oravariablepropertythatstoresavaluethatisglobaltoallinstancesofthattype(likeastaticvariableinC).

Storedtypepropertiescanbevariablesorconstants.Computedtypepropertiesarealwaysdeclaredasvariableproperties,inthesamewayascomputedinstanceproperties.

NOTE

Unlikestoredinstanceproperties,youmustalwaysgivestoredtypepropertiesadefaultvalue.Thisisbecausethetypeitselfdoesnothaveaninitializerthatcanassignavaluetoastoredtypepropertyatinitializationtime.

Storedtypepropertiesarelazilyinitializedontheirfirstaccess.Theyareguaranteedtobeinitializedonlyonce,evenwhenaccessedbymultiplethreadssimultaneously,andtheydonotneedtobemarkedwiththelazymodifier.

TypePropertySyntaxInCandObjective-C,youdefinestaticconstantsandvariablesassociatedwithatypeasglobalstaticvariables.InSwift,however,typepropertiesarewrittenaspartofthetype’sdefinition,withinthetype’soutercurlybraces,andeachtypepropertyisexplicitlyscopedtothetypeitsupports.

Youdefinetypepropertieswiththestatickeyword.Forcomputedtypepropertiesforclasstypes,youcanusetheclasskeywordinsteadtoallowsubclassestooverridethesuperclass’simplementation.Theexamplebelowshowsthesyntaxforstoredandcomputedtypeproperties:

1 structSomeStructure{

2 staticvarstoredTypeProperty="Somevalue."

3 staticvarcomputedTypeProperty:Int{

4 return1

5 }

6 }

7 enumSomeEnumeration{

Page 253: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 staticvarstoredTypeProperty="Somevalue."

9 staticvarcomputedTypeProperty:Int{

10 return6

11 }

12 }

13 classSomeClass{

14 staticvarstoredTypeProperty="Somevalue."

15 staticvarcomputedTypeProperty:Int{

16 return27

17 }

18 classvaroverrideableComputedTypeProperty:Int{

19 return107

20 }

21 }

NOTE

Thecomputedtypepropertyexamplesaboveareforread-onlycomputedtypeproperties,butyoucanalsodefineread-writecomputedtypepropertieswiththesamesyntaxasforcomputedinstanceproperties.

QueryingandSettingTypePropertiesTypepropertiesarequeriedandsetwithdotsyntax,justlikeinstanceproperties.However,typepropertiesarequeriedandsetonthetype,notonaninstanceofthattype.Forexample:

1 print(SomeStructure.storedTypeProperty)

2 //Prints"Somevalue."

3 SomeStructure.storedTypeProperty="Anothervalue."

4 print(SomeStructure.storedTypeProperty)

5 //Prints"Anothervalue."

Page 254: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 print(SomeEnumeration.computedTypeProperty)

7 //Prints"6"

8 print(SomeClass.computedTypeProperty)

9 //Prints"27"

Theexamplesthatfollowusetwostoredtypepropertiesaspartofastructurethatmodelsanaudiolevelmeterforanumberofaudiochannels.Eachchannelhasanintegeraudiolevelbetween0and10inclusive.

Thefigurebelowillustrateshowtwooftheseaudiochannelscanbecombinedtomodelastereoaudiolevelmeter.Whenachannel’saudiolevelis0,noneofthelightsforthatchannelarelit.Whentheaudiolevelis10,allofthelightsforthatchannelarelit.Inthisfigure,theleftchannelhasacurrentlevelof9,andtherightchannelhasacurrentlevelof7:

TheaudiochannelsdescribedabovearerepresentedbyinstancesoftheAudioChannelstructure:

1 structAudioChannel{

2 staticletthresholdLevel=10

Page 255: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 staticvarmaxInputLevelForAllChannels=0

4 varcurrentLevel:Int=0{

5 didSet{

6 ifcurrentLevel>AudioChannel.thresholdLevel{

7 //capthenewaudioleveltothethreshold

level

8 currentLevel=AudioChannel.thresholdLevel

9 }

10 ifcurrentLevel>

AudioChannel.maxInputLevelForAllChannels{

11 //storethisasthenewoverallmaximuminput

level

12 AudioChannel.maxInputLevelForAllChannels=

currentLevel

13 }

14 }

15 }

16 }

TheAudioChannelstructuredefinestwostoredtypepropertiestosupportitsfunctionality.Thefirst,thresholdLevel,definesthemaximumthresholdvalueanaudiolevelcantake.Thisisaconstantvalueof10forallAudioChannelinstances.Ifanaudiosignalcomesinwithahighervaluethan10,itwillbecappedtothisthresholdvalue(asdescribedbelow).

ThesecondtypepropertyisavariablestoredpropertycalledmaxInputLevelForAllChannels.ThiskeepstrackofthemaximuminputvaluethathasbeenreceivedbyanyAudioChannelinstance.Itstartswithaninitialvalueof0.

TheAudioChannelstructurealsodefinesastoredinstancepropertycalledcurrentLevel,whichrepresentsthechannel’scurrentaudiolevelonascaleof0to10.

Page 256: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThecurrentLevelpropertyhasadidSetpropertyobservertocheckthevalueofcurrentLevelwheneveritisset.Thisobserverperformstwochecks:

IfthenewvalueofcurrentLevelisgreaterthantheallowedthresholdLevel,thepropertyobservercapscurrentLeveltothresholdLevel.

IfthenewvalueofcurrentLevel(afteranycapping)ishigherthananyvaluepreviouslyreceivedbyanyAudioChannelinstance,thepropertyobserverstoresthenewcurrentLevelvalueinthemaxInputLevelForAllChannelstypeproperty.

NOTE

Inthefirstofthesetwochecks,thedidSetobserversetscurrentLeveltoadifferentvalue.Thisdoesnot,however,causetheobservertobecalledagain.

YoucanusetheAudioChannelstructuretocreatetwonewaudiochannelscalledleftChannelandrightChannel,torepresenttheaudiolevelsofastereosoundsystem:

1 varleftChannel=AudioChannel()

2 varrightChannel=AudioChannel()

IfyousetthecurrentLeveloftheleftchannelto7,youcanseethatthemaxInputLevelForAllChannelstypepropertyisupdatedtoequal7:

1 leftChannel.currentLevel=7

2 print(leftChannel.currentLevel)

3 //Prints"7"

4 print(AudioChannel.maxInputLevelForAllChannels)

5 //Prints"7"

IfyoutrytosetthecurrentLeveloftherightchannelto11,youcanseethattherightchannel’scurrentLevelpropertyiscappedtothemaximumvalueof10,andthemaxInputLevelForAllChannelstypepropertyisupdatedtoequal10:

Page 257: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 rightChannel.currentLevel=11

2 print(rightChannel.currentLevel)

3 //Prints"10"

4 print(AudioChannel.maxInputLevelForAllChannels)

5 //Prints"10"

Page 258: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Methods

Methodsarefunctionsthatareassociatedwithaparticulartype.Classes,structures,andenumerationscanalldefineinstancemethods,whichencapsulatespecifictasksandfunctionalityforworkingwithaninstanceofagiventype.Classes,structures,andenumerationscanalsodefinetypemethods,whichareassociatedwiththetypeitself.TypemethodsaresimilartoclassmethodsinObjective-C.

ThefactthatstructuresandenumerationscandefinemethodsinSwiftisamajordifferencefromCandObjective-C.InObjective-C,classesaretheonlytypesthatcandefinemethods.InSwift,youcanchoosewhethertodefineaclass,structure,orenumeration,andstillhavetheflexibilitytodefinemethodsonthetypeyoucreate.

InstanceMethods

Instancemethodsarefunctionsthatbelongtoinstancesofaparticularclass,structure,orenumeration.Theysupportthefunctionalityofthoseinstances,eitherbyprovidingwaystoaccessandmodifyinstanceproperties,orbyprovidingfunctionalityrelatedtotheinstance’spurpose.Instancemethodshaveexactlythesamesyntaxasfunctions,asdescribedinFunctions.

Youwriteaninstancemethodwithintheopeningandclosingbracesofthetypeitbelongsto.Aninstancemethodhasimplicitaccesstoallotherinstancemethodsandpropertiesofthattype.Aninstancemethodcanbecalledonlyonaspecificinstanceofthetypeitbelongsto.Itcannotbecalledinisolationwithoutanexistinginstance.

Here’sanexamplethatdefinesasimpleCounterclass,whichcanbeusedtocountthenumberoftimesanactionoccurs:

1 classCounter{

Page 259: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 varcount=0

3 funcincrement(){

4 count+=1

5 }

6 funcincrement(byamount:Int){

7 count+=amount

8 }

9 funcreset(){

10 count=0

11 }

12 }

TheCounterclassdefinesthreeinstancemethods:

increment()incrementsthecounterby1.

increment(by:Int)incrementsthecounterbyaspecifiedintegeramount.

reset()resetsthecountertozero.

TheCounterclassalsodeclaresavariableproperty,count,tokeeptrackofthecurrentcountervalue.

Youcallinstancemethodswiththesamedotsyntaxasproperties:

1 letcounter=Counter()

2 //theinitialcountervalueis0

3 counter.increment()

4 //thecounter'svalueisnow1

5 counter.increment(by:5)

6 //thecounter'svalueisnow6

7 counter.reset()

8 //thecounter'svalueisnow0

Page 260: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Functionparameterscanhavebothaname(forusewithinthefunction’sbody)andanargumentlabel(forusewhencallingthefunction),asdescribedinFunctionArgumentLabelsandParameterNames.Thesameistrueformethodparameters,becausemethodsarejustfunctionsthatareassociatedwithatype.

TheselfPropertyEveryinstanceofatypehasanimplicitpropertycalledself,whichisexactlyequivalenttotheinstanceitself.Youusetheselfpropertytorefertothecurrentinstancewithinitsowninstancemethods.

Theincrement()methodintheexampleabovecouldhavebeenwrittenlikethis:

1 funcincrement(){

2 self.count+=1

3 }

Inpractice,youdon’tneedtowriteselfinyourcodeveryoften.Ifyoudon’texplicitlywriteself,Swiftassumesthatyouarereferringtoapropertyormethodofthecurrentinstancewheneveryouuseaknownpropertyormethodnamewithinamethod.Thisassumptionisdemonstratedbytheuseofcount(ratherthanself.count)insidethethreeinstancemethodsforCounter.

Themainexceptiontothisruleoccurswhenaparameternameforaninstancemethodhasthesamenameasapropertyofthatinstance.Inthissituation,theparameternametakesprecedence,anditbecomesnecessarytorefertothepropertyinamorequalifiedway.Youusetheselfpropertytodistinguishbetweentheparameternameandthepropertyname.

Here,selfdisambiguatesbetweenamethodparametercalledxandaninstancepropertythatisalsocalledx:

1 structPoint{

2 varx=0.0,y=0.0

3 funcisToTheRightOf(x:Double)->Bool{

Page 261: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 returnself.x>x

5 }

6 }

7 letsomePoint=Point(x:4.0,y:5.0)

8 ifsomePoint.isToTheRightOf(x:1.0){

9 print("Thispointistotherightofthelinewherex==

1.0")

10 }

11 //Prints"Thispointistotherightofthelinewherex==

1.0"

Withouttheselfprefix,Swiftwouldassumethatbothusesofxreferredtothemethodparametercalledx.

ModifyingValueTypesfromWithinInstanceMethodsStructuresandenumerationsarevaluetypes.Bydefault,thepropertiesofavaluetypecannotbemodifiedfromwithinitsinstancemethods.

However,ifyouneedtomodifythepropertiesofyourstructureorenumerationwithinaparticularmethod,youcanoptintomutatingbehaviorforthatmethod.Themethodcanthenmutate(thatis,change)itspropertiesfromwithinthemethod,andanychangesthatitmakesarewrittenbacktotheoriginalstructurewhenthemethodends.Themethodcanalsoassignacompletelynewinstancetoitsimplicitselfproperty,andthisnewinstancewillreplacetheexistingonewhenthemethodends.

Youcanoptintothisbehaviorbyplacingthemutatingkeywordbeforethefunckeywordforthatmethod:

1 structPoint{

2 varx=0.0,y=0.0

3 mutatingfuncmoveBy(xdeltaX:Double,ydeltaY:Double){

Page 262: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 x+=deltaX

5 y+=deltaY

6 }

7 }

8 varsomePoint=Point(x:1.0,y:1.0)

9 somePoint.moveBy(x:2.0,y:3.0)

10 print("Thepointisnowat(\(somePoint.x),\(somePoint.y))")

11 //Prints"Thepointisnowat(3.0,4.0)"

ThePointstructureabovedefinesamutatingmoveBy(x:y:)method,whichmovesaPointinstancebyacertainamount.Insteadofreturninganewpoint,thismethodactuallymodifiesthepointonwhichitiscalled.Themutatingkeywordisaddedtoitsdefinitiontoenableittomodifyitsproperties.

Notethatyoucannotcallamutatingmethodonaconstantofstructuretype,becauseitspropertiescannotbechanged,eveniftheyarevariableproperties,asdescribedinStoredPropertiesofConstantStructureInstances:

1 letfixedPoint=Point(x:3.0,y:3.0)

2 fixedPoint.moveBy(x:2.0,y:3.0)

3 //thiswillreportanerror

AssigningtoselfWithinaMutatingMethodMutatingmethodscanassignanentirelynewinstancetotheimplicitselfproperty.ThePointexampleshownabovecouldhavebeenwritteninthefollowingwayinstead:

1 structPoint{

2 varx=0.0,y=0.0

3 mutatingfuncmoveBy(xdeltaX:Double,ydeltaY:Double){

4 self=Point(x:x+deltaX,y:y+deltaY)

Page 263: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 }

6 }

ThisversionofthemutatingmoveBy(x:y:)methodcreatesanewstructurewhosexandyvaluesaresettothetargetlocation.Theendresultofcallingthisalternativeversionofthemethodwillbeexactlythesameasforcallingtheearlierversion.

Mutatingmethodsforenumerationscansettheimplicitselfparametertobeadifferentcasefromthesameenumeration:

1 enumTriStateSwitch{

2 caseoff,low,high

3 mutatingfuncnext(){

4 switchself{

5 case.off:

6 self=.low

7 case.low:

8 self=.high

9 case.high:

10 self=.off

11 }

12 }

13 }

14 varovenLight=TriStateSwitch.low

15 ovenLight.next()

16 //ovenLightisnowequalto.high

17 ovenLight.next()

18 //ovenLightisnowequalto.off

Thisexampledefinesanenumerationforathree-stateswitch.Theswitchcyclesbetweenthreedifferentpowerstates(off,lowandhigh)everytimeitsnext()

Page 264: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

methodiscalled.

TypeMethods

Instancemethods,asdescribedabove,aremethodsthatyoucallonaninstanceofaparticulartype.Youcanalsodefinemethodsthatarecalledonthetypeitself.Thesekindsofmethodsarecalledtypemethods.Youindicatetypemethodsbywritingthestatickeywordbeforethemethod’sfunckeyword.Classescanusetheclasskeywordinstead,toallowsubclassestooverridethesuperclass’simplementationofthatmethod.

NOTE

InObjective-C,youcandefinetype-levelmethodsonlyforObjective-Cclasses.InSwift,youcandefinetype-levelmethodsforallclasses,structures,andenumerations.Eachtypemethodisexplicitlyscopedtothetypeitsupports.

Typemethodsarecalledwithdotsyntax,likeinstancemethods.However,youcalltypemethodsonthetype,notonaninstanceofthattype.Here’showyoucallatypemethodonaclasscalledSomeClass:

1 classSomeClass{

2 classfuncsomeTypeMethod(){

3 //typemethodimplementationgoeshere

4 }

5 }

6 SomeClass.someTypeMethod()

Withinthebodyofatypemethod,theimplicitselfpropertyreferstothetypeitself,ratherthananinstanceofthattype.Thismeansthatyoucanuseselftodisambiguatebetweentypepropertiesandtypemethodparameters,justasyoudoforinstancepropertiesandinstancemethodparameters.

Moregenerally,anyunqualifiedmethodandpropertynamesthatyouusewithin

Page 265: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thebodyofatypemethodwillrefertoothertype-levelmethodsandproperties.Atypemethodcancallanothertypemethodwiththeothermethod’sname,withoutneedingtoprefixitwiththetypename.Similarly,typemethodsonstructuresandenumerationscanaccesstypepropertiesbyusingthetypeproperty’snamewithoutatypenameprefix.

TheexamplebelowdefinesastructurecalledLevelTracker,whichtracksaplayer’sprogressthroughthedifferentlevelsorstagesofagame.Itisasingle-playergame,butcanstoreinformationformultipleplayersonasingledevice.

Allofthegame’slevels(apartfromlevelone)arelockedwhenthegameisfirstplayed.Everytimeaplayerfinishesalevel,thatlevelisunlockedforallplayersonthedevice.TheLevelTrackerstructureusestypepropertiesandmethodstokeeptrackofwhichlevelsofthegamehavebeenunlocked.Italsotracksthecurrentlevelforanindividualplayer.

1 structLevelTracker{

2 staticvarhighestUnlockedLevel=1

3 varcurrentLevel=1

4

5 staticfuncunlock(_level:Int){

6 iflevel>highestUnlockedLevel{highestUnlockedLevel

=level}

7 }

8

9 staticfuncisUnlocked(_level:Int)->Bool{

10 returnlevel<=highestUnlockedLevel

11 }

12

13 @discardableResult

14 mutatingfuncadvance(tolevel:Int)->Bool{

15 ifLevelTracker.isUnlocked(level){

16 currentLevel=level

Page 266: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

17 returntrue

18 }else{

19 returnfalse

20 }

21 }

22 }

TheLevelTrackerstructurekeepstrackofthehighestlevelthatanyplayerhasunlocked.ThisvalueisstoredinatypepropertycalledhighestUnlockedLevel.

LevelTrackeralsodefinestwotypefunctionstoworkwiththehighestUnlockedLevelproperty.Thefirstisatypefunctioncalledunlock(_:),whichupdatesthevalueofhighestUnlockedLevelwheneveranewlevelisunlocked.ThesecondisaconveniencetypefunctioncalledisUnlocked(_:),whichreturnstrueifaparticularlevelnumberisalreadyunlocked.(NotethatthesetypemethodscanaccessthehighestUnlockedLeveltypepropertywithoutyourneedingtowriteitasLevelTracker.highestUnlockedLevel.)

Inadditiontoitstypepropertyandtypemethods,LevelTrackertracksanindividualplayer’sprogressthroughthegame.ItusesaninstancepropertycalledcurrentLeveltotrackthelevelthataplayeriscurrentlyplaying.

TohelpmanagethecurrentLevelproperty,LevelTrackerdefinesaninstancemethodcalledadvance(to:).BeforeupdatingcurrentLevel,thismethodcheckswhethertherequestednewlevelisalreadyunlocked.Theadvance(to:)methodreturnsaBooleanvaluetoindicatewhetherornotitwasactuallyabletosetcurrentLevel.Becauseit’snotnecessarilyamistakeforcodethatcallstheadvance(to:)methodtoignorethereturnvalue,thisfunctionismarkedwiththe@discardableResultattribute.Formoreinformationaboutthisattribute,seeAttributes.

TheLevelTrackerstructureisusedwiththePlayerclass,shownbelow,totrackandupdatetheprogressofanindividualplayer:

1 classPlayer{

2 vartracker=LevelTracker()

Page 267: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 letplayerName:String

4 funccomplete(level:Int){

5 LevelTracker.unlock(level+1)

6 tracker.advance(to:level+1)

7 }

8 init(name:String){

9 playerName=name

10 }

11 }

ThePlayerclasscreatesanewinstanceofLevelTrackertotrackthatplayer’sprogress.Italsoprovidesamethodcalledcomplete(level:),whichiscalledwheneveraplayercompletesaparticularlevel.Thismethodunlocksthenextlevelforallplayersandupdatestheplayer’sprogresstomovethemtothenextlevel.(TheBooleanreturnvalueofadvance(to:)isignored,becausethelevelisknowntohavebeenunlockedbythecalltoLevelTracker.unlock(_:)onthepreviousline.)

YoucancreateaninstanceofthePlayerclassforanewplayer,andseewhathappenswhentheplayercompleteslevelone:

1 varplayer=Player(name:"Argyrios")

2 player.complete(level:1)

3 print("highestunlockedlevelisnow\

(LevelTracker.highestUnlockedLevel)")

4 //Prints"highestunlockedlevelisnow2"

Ifyoucreateasecondplayer,whomyoutrytomovetoalevelthatisnotyetunlockedbyanyplayerinthegame,theattempttosettheplayer’scurrentlevelfails:

1 player=Player(name:"Beto")

2 ifplayer.tracker.advance(to:6){

Page 268: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 print("playerisnowonlevel6")

4 }else{

5 print("level6hasnotyetbeenunlocked")

6 }

7 //Prints"level6hasnotyetbeenunlocked"

Page 269: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Subscripts

Classes,structures,andenumerationscandefinesubscripts,whichareshortcutsforaccessingthememberelementsofacollection,list,orsequence.Youusesubscriptstosetandretrievevaluesbyindexwithoutneedingseparatemethodsforsettingandretrieval.Forexample,youaccesselementsinanArrayinstanceassomeArray[index]andelementsinaDictionaryinstanceassomeDictionary[key].

Youcandefinemultiplesubscriptsforasingletype,andtheappropriatesubscriptoverloadtouseisselectedbasedonthetypeofindexvalueyoupasstothesubscript.Subscriptsarenotlimitedtoasingledimension,andyoucandefinesubscriptswithmultipleinputparameterstosuityourcustomtype’sneeds.

SubscriptSyntax

Subscriptsenableyoutoqueryinstancesofatypebywritingoneormorevaluesinsquarebracketsaftertheinstancename.Theirsyntaxissimilartobothinstancemethodsyntaxandcomputedpropertysyntax.Youwritesubscriptdefinitionswiththesubscriptkeyword,andspecifyoneormoreinputparametersandareturntype,inthesamewayasinstancemethods.Unlikeinstancemethods,subscriptscanberead-writeorread-only.Thisbehavioriscommunicatedbyagetterandsetterinthesamewayasforcomputedproperties:

1 subscript(index:Int)->Int{

2 get{

3 //Returnanappropriatesubscriptvaluehere.

4 }

5 set(newValue){

6 //Performasuitablesettingactionhere.

Page 270: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

7 }

8 }

ThetypeofnewValueisthesameasthereturnvalueofthesubscript.Aswithcomputedproperties,youcanchoosenottospecifythesetter’s(newValue)parameter.AdefaultparametercallednewValueisprovidedtoyoursetterifyoudonotprovideoneyourself.

Aswithread-onlycomputedproperties,youcansimplifythedeclarationofaread-onlysubscriptbyremovingthegetkeywordanditsbraces:

1 subscript(index:Int)->Int{

2 //Returnanappropriatesubscriptvaluehere.

3 }

Here’sanexampleofaread-onlysubscriptimplementation,whichdefinesaTimesTablestructuretorepresentann-times-tableofintegers:

1 structTimesTable{

2 letmultiplier:Int

3 subscript(index:Int)->Int{

4 returnmultiplier*index

5 }

6 }

7 letthreeTimesTable=TimesTable(multiplier:3)

8 print("sixtimesthreeis\(threeTimesTable[6])")

9 //Prints"sixtimesthreeis18"

Inthisexample,anewinstanceofTimesTableiscreatedtorepresentthethree-times-table.Thisisindicatedbypassingavalueof3tothestructure’sinitializerasthevaluetousefortheinstance’smultiplierparameter.

YoucanquerythethreeTimesTableinstancebycallingitssubscript,asshowninthecalltothreeTimesTable[6].Thisrequeststhesixthentryinthethree-times-

Page 271: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

table,whichreturnsavalueof18,or3times6.

NOTE

Ann-times-tableisbasedonafixedmathematicalrule.ItisnotappropriatetosetthreeTimesTable[someIndex]toanewvalue,andsothesubscriptforTimesTableisdefinedasaread-onlysubscript.

SubscriptUsage

Theexactmeaningof“subscript”dependsonthecontextinwhichitisused.Subscriptsaretypicallyusedasashortcutforaccessingthememberelementsinacollection,list,orsequence.Youarefreetoimplementsubscriptsinthemostappropriatewayforyourparticularclassorstructure’sfunctionality.

Forexample,Swift’sDictionarytypeimplementsasubscripttosetandretrievethevaluesstoredinaDictionaryinstance.Youcansetavalueinadictionarybyprovidingakeyofthedictionary’skeytypewithinsubscriptbrackets,andassigningavalueofthedictionary’svaluetypetothesubscript:

1 varnumberOfLegs=["spider":8,"ant":6,"cat":4]

2 numberOfLegs["bird"]=2

TheexampleabovedefinesavariablecallednumberOfLegsandinitializesitwithadictionaryliteralcontainingthreekey-valuepairs.ThetypeofthenumberOfLegsdictionaryisinferredtobe[String:Int].Aftercreatingthedictionary,thisexampleusessubscriptassignmenttoaddaStringkeyof"bird"andanIntvalueof2tothedictionary.

FormoreinformationaboutDictionarysubscripting,seeAccessingandModifyingaDictionary.

NOTE

Swift’sDictionarytypeimplementsitskey-valuesubscriptingasasubscriptthattakesandreturnsanoptionaltype.ForthenumberOfLegsdictionaryabove,thekey-valuesubscripttakesandreturnsavalueoftypeInt?,or“optionalint”.TheDictionarytypeusesanoptional

Page 272: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

subscripttypetomodelthefactthatnoteverykeywillhaveavalue,andtogiveawaytodeleteavalueforakeybyassigninganilvalueforthatkey.

SubscriptOptions

Subscriptscantakeanynumberofinputparameters,andtheseinputparameterscanbeofanytype.Subscriptscanalsoreturnanytype.Subscriptscanusevariadicparameters,buttheycan’tusein-outparametersorprovidedefaultparametervalues.

Aclassorstructurecanprovideasmanysubscriptimplementationsasitneeds,andtheappropriatesubscripttobeusedwillbeinferredbasedonthetypesofthevalueorvaluesthatarecontainedwithinthesubscriptbracketsatthepointthatthesubscriptisused.Thisdefinitionofmultiplesubscriptsisknownassubscriptoverloading.

Whileitismostcommonforasubscripttotakeasingleparameter,youcanalsodefineasubscriptwithmultipleparametersifitisappropriateforyourtype.ThefollowingexampledefinesaMatrixstructure,whichrepresentsatwo-dimensionalmatrixofDoublevalues.TheMatrixstructure’ssubscripttakestwointegerparameters:

1 structMatrix{

2 letrows:Int,columns:Int

3 vargrid:[Double]

4 init(rows:Int,columns:Int){

5 self.rows=rows

6 self.columns=columns

7 grid=Array(repeating:0.0,count:rows*columns)

8 }

9 funcindexIsValid(row:Int,column:Int)->Bool{

10 returnrow>=0&&row<rows&&column>=0&&column

Page 273: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

<columns

11 }

12 subscript(row:Int,column:Int)->Double{

13 get{

14 assert(indexIsValid(row:row,column:column),

"Indexoutofrange")

15 returngrid[(row*columns)+column]

16 }

17 set{

18 assert(indexIsValid(row:row,column:column),

"Indexoutofrange")

19 grid[(row*columns)+column]=newValue

20 }

21 }

22 }

Matrixprovidesaninitializerthattakestwoparameterscalledrowsandcolumns,andcreatesanarraythatislargeenoughtostorerows*columnsvaluesoftypeDouble.Eachpositioninthematrixisgivenaninitialvalueof0.0.Toachievethis,thearray’ssize,andaninitialcellvalueof0.0,arepassedtoanarrayinitializerthatcreatesandinitializesanewarrayofthecorrectsize.ThisinitializerisdescribedinmoredetailinCreatinganArraywithaDefaultValue.

YoucanconstructanewMatrixinstancebypassinganappropriaterowandcolumncounttoitsinitializer:

varmatrix=Matrix(rows:2,columns:2)

TheexampleabovecreatesanewMatrixinstancewithtworowsandtwocolumns.ThegridarrayforthisMatrixinstanceiseffectivelyaflattenedversionofthematrix,asreadfromtoplefttobottomright:

Page 274: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Valuesinthematrixcanbesetbypassingrowandcolumnvaluesintothesubscript,separatedbyacomma:

1 matrix[0,1]=1.5

2 matrix[1,0]=3.2

Thesetwostatementscallthesubscript’ssettertosetavalueof1.5inthetoprightpositionofthematrix(whererowis0andcolumnis1),and3.2inthebottomleftposition(whererowis1andcolumnis0):

TheMatrixsubscript’sgetterandsetterbothcontainanassertiontocheckthatthesubscript’srowandcolumnvaluesarevalid.Toassistwiththeseassertions,MatrixincludesaconveniencemethodcalledindexIsValid(row:column:),whichcheckswhethertherequestedrowandcolumnareinsidetheboundsofthematrix:

1 funcindexIsValid(row:Int,column:Int)->Bool{

2 returnrow>=0&&row<rows&&column>=0&&column<

columns

3 }

Anassertionistriggeredifyoutrytoaccessasubscriptthatisoutsideofthematrixbounds:

Page 275: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letsomeValue=matrix[2,2]

2 //Thistriggersanassert,because[2,2]isoutsideofthe

matrixbounds.

TypeSubscripts

Instancesubscripts,asdescribedabove,aresubscriptsthatyoucallonaninstanceofaparticulartype.Youcanalsodefinesubscriptsthatarecalledonthetypeitself.Thiskindofsubscriptiscalledatypesubscript.Youindicateatypesubscriptbywritingthestatickeywordbeforethesubscriptkeyword.Classescanusetheclasskeywordinstead,toallowsubclassestooverridethesuperclass’simplementationofthatsubscript.Theexamplebelowshowshowyoudefineandcallatypesubscript:

1 enumPlanet:Int{

2 casemercury=1,venus,earth,mars,jupiter,saturn,

uranus,neptune

3 staticsubscript(n:Int)->Planet{

4 returnPlanet(rawValue:n)!

5 }

6 }

7 letmars=Planet[4]

8 print(mars)

Page 276: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Inheritance

Aclasscaninheritmethods,properties,andothercharacteristicsfromanotherclass.Whenoneclassinheritsfromanother,theinheritingclassisknownasasubclass,andtheclassitinheritsfromisknownasitssuperclass.InheritanceisafundamentalbehaviorthatdifferentiatesclassesfromothertypesinSwift.

ClassesinSwiftcancallandaccessmethods,properties,andsubscriptsbelongingtotheirsuperclassandcanprovidetheirownoverridingversionsofthosemethods,properties,andsubscriptstorefineormodifytheirbehavior.Swifthelpstoensureyouroverridesarecorrectbycheckingthattheoverridedefinitionhasamatchingsuperclassdefinition.

Classescanalsoaddpropertyobserverstoinheritedpropertiesinordertobenotifiedwhenthevalueofapropertychanges.Propertyobserverscanbeaddedtoanyproperty,regardlessofwhetheritwasoriginallydefinedasastoredorcomputedproperty.

DefiningaBaseClass

Anyclassthatdoesnotinheritfromanotherclassisknownasabaseclass.

NOTE

Swiftclassesdonotinheritfromauniversalbaseclass.Classesyoudefinewithoutspecifyingasuperclassautomaticallybecomebaseclassesforyoutobuildupon.

TheexamplebelowdefinesabaseclasscalledVehicle.ThisbaseclassdefinesastoredpropertycalledcurrentSpeed,withadefaultvalueof0.0(inferringapropertytypeofDouble).ThecurrentSpeedproperty’svalueisusedbyaread-onlycomputedStringpropertycalleddescriptiontocreateadescriptionofthevehicle.

TheVehiclebaseclassalsodefinesamethodcalledmakeNoise.Thismethod

Page 277: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

doesnotactuallydoanythingforabaseVehicleinstance,butwillbecustomizedbysubclassesofVehiclelateron:

1 classVehicle{

2 varcurrentSpeed=0.0

3 vardescription:String{

4 return"travelingat\(currentSpeed)milesperhour"

5 }

6 funcmakeNoise(){

7 //donothing-anarbitraryvehicledoesn't

necessarilymakeanoise

8 }

9 }

YoucreateanewinstanceofVehiclewithinitializersyntax,whichiswrittenasatypenamefollowedbyemptyparentheses:

letsomeVehicle=Vehicle()

HavingcreatedanewVehicleinstance,youcanaccessitsdescriptionpropertytoprintahuman-readabledescriptionofthevehicle’scurrentspeed:

1 print("Vehicle:\(someVehicle.description)")

2 //Vehicle:travelingat0.0milesperhour

TheVehicleclassdefinescommoncharacteristicsforanarbitraryvehicle,butisnotmuchuseinitself.Tomakeitmoreuseful,youneedtorefineittodescribemorespecifickindsofvehicles.

Subclassing

Subclassingistheactofbasinganewclassonanexistingclass.Thesubclass

Page 278: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

inheritscharacteristicsfromtheexistingclass,whichyoucanthenrefine.Youcanalsoaddnewcharacteristicstothesubclass.

Toindicatethatasubclasshasasuperclass,writethesubclassnamebeforethesuperclassname,separatedbyacolon:

1 classSomeSubclass:SomeSuperclass{

2 //subclassdefinitiongoeshere

3 }

ThefollowingexampledefinesasubclasscalledBicycle,withasuperclassofVehicle:

1 classBicycle:Vehicle{

2 varhasBasket=false

3 }

ThenewBicycleclassautomaticallygainsallofthecharacteristicsofVehicle,suchasitscurrentSpeedanddescriptionpropertiesanditsmakeNoise()method.

Inadditiontothecharacteristicsitinherits,theBicycleclassdefinesanewstoredproperty,hasBasket,withadefaultvalueoffalse(inferringatypeofBoolfortheproperty).

Bydefault,anynewBicycleinstanceyoucreatewillnothaveabasket.YoucansetthehasBasketpropertytotrueforaparticularBicycleinstanceafterthatinstanceiscreated:

1 letbicycle=Bicycle()

2 bicycle.hasBasket=true

YoucanalsomodifytheinheritedcurrentSpeedpropertyofaBicycleinstance,andquerytheinstance’sinheriteddescriptionproperty:

1 bicycle.currentSpeed=15.0

Page 279: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 print("Bicycle:\(bicycle.description)")

3 //Bicycle:travelingat15.0milesperhour

Subclassescanthemselvesbesubclassed.ThenextexamplecreatesasubclassofBicycleforatwo-seaterbicycleknownasa“tandem”:

1 classTandem:Bicycle{

2 varcurrentNumberOfPassengers=0

3 }

TandeminheritsallofthepropertiesandmethodsfromBicycle,whichinturninheritsallofthepropertiesandmethodsfromVehicle.TheTandemsubclassalsoaddsanewstoredpropertycalledcurrentNumberOfPassengers,withadefaultvalueof0.

IfyoucreateaninstanceofTandem,youcanworkwithanyofitsnewandinheritedproperties,andquerytheread-onlydescriptionpropertyitinheritsfromVehicle:

1 lettandem=Tandem()

2 tandem.hasBasket=true

3 tandem.currentNumberOfPassengers=2

4 tandem.currentSpeed=22.0

5 print("Tandem:\(tandem.description)")

6 //Tandem:travelingat22.0milesperhour

Overriding

Asubclasscanprovideitsowncustomimplementationofaninstancemethod,typemethod,instanceproperty,typeproperty,orsubscriptthatitwouldotherwiseinheritfromasuperclass.Thisisknownasoverriding.

Page 280: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Tooverrideacharacteristicthatwouldotherwisebeinherited,youprefixyouroverridingdefinitionwiththeoverridekeyword.Doingsoclarifiesthatyouintendtoprovideanoverrideandhavenotprovidedamatchingdefinitionbymistake.Overridingbyaccidentcancauseunexpectedbehavior,andanyoverrideswithouttheoverridekeywordarediagnosedasanerrorwhenyourcodeiscompiled.

TheoverridekeywordalsopromptstheSwiftcompilertocheckthatyouroverridingclass’ssuperclass(oroneofitsparents)hasadeclarationthatmatchestheoneyouprovidedfortheoverride.Thischeckensuresthatyouroverridingdefinitioniscorrect.

AccessingSuperclassMethods,Properties,andSubscriptsWhenyouprovideamethod,property,orsubscriptoverrideforasubclass,itissometimesusefultousetheexistingsuperclassimplementationaspartofyouroverride.Forexample,youcanrefinethebehaviorofthatexistingimplementation,orstoreamodifiedvalueinanexistinginheritedvariable.

Wherethisisappropriate,youaccessthesuperclassversionofamethod,property,orsubscriptbyusingthesuperprefix:

AnoverriddenmethodnamedsomeMethod()cancallthesuperclassversionofsomeMethod()bycallingsuper.someMethod()withintheoverridingmethodimplementation.

AnoverriddenpropertycalledsomePropertycanaccessthesuperclassversionofsomePropertyassuper.somePropertywithintheoverridinggetterorsetterimplementation.

AnoverriddensubscriptforsomeIndexcanaccessthesuperclassversionofthesamesubscriptassuper[someIndex]fromwithintheoverridingsubscriptimplementation.

OverridingMethods

Page 281: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youcanoverrideaninheritedinstanceortypemethodtoprovideatailoredoralternativeimplementationofthemethodwithinyoursubclass.

ThefollowingexampledefinesanewsubclassofVehiclecalledTrain,whichoverridesthemakeNoise()methodthatTraininheritsfromVehicle:

1 classTrain:Vehicle{

2 overridefuncmakeNoise(){

3 print("ChooChoo")

4 }

5 }

IfyoucreateanewinstanceofTrainandcallitsmakeNoise()method,youcanseethattheTrainsubclassversionofthemethodiscalled:

1 lettrain=Train()

2 train.makeNoise()

3 //Prints"ChooChoo"

OverridingPropertiesYoucanoverrideaninheritedinstanceortypepropertytoprovideyourowncustomgetterandsetterforthatproperty,ortoaddpropertyobserverstoenabletheoverridingpropertytoobservewhentheunderlyingpropertyvaluechanges.

OverridingPropertyGettersandSetters

Youcanprovideacustomgetter(andsetter,ifappropriate)tooverrideanyinheritedproperty,regardlessofwhethertheinheritedpropertyisimplementedasastoredorcomputedpropertyatsource.Thestoredorcomputednatureofaninheritedpropertyisnotknownbyasubclass—itonlyknowsthattheinheritedpropertyhasacertainnameandtype.Youmustalwaysstateboththenameandthetypeofthepropertyyouareoverriding,toenablethecompilertocheckthatyouroverridematchesasuperclasspropertywiththesamenameandtype.

Page 282: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youcanpresentaninheritedread-onlypropertyasaread-writepropertybyprovidingbothagetterandasetterinyoursubclasspropertyoverride.Youcannot,however,presentaninheritedread-writepropertyasaread-onlyproperty.

NOTE

Ifyouprovideasetteraspartofapropertyoverride,youmustalsoprovideagetterforthatoverride.Ifyoudon’twanttomodifytheinheritedproperty’svaluewithintheoverridinggetter,youcansimplypassthroughtheinheritedvaluebyreturningsuper.somePropertyfromthegetter,wheresomePropertyisthenameofthepropertyyouareoverriding.

ThefollowingexampledefinesanewclasscalledCar,whichisasubclassofVehicle.TheCarclassintroducesanewstoredpropertycalledgear,withadefaultintegervalueof1.TheCarclassalsooverridesthedescriptionpropertyitinheritsfromVehicle,toprovideacustomdescriptionthatincludesthecurrentgear:

1 classCar:Vehicle{

2 vargear=1

3 overridevardescription:String{

4 returnsuper.description+"ingear\(gear)"

5 }

6 }

Theoverrideofthedescriptionpropertystartsbycallingsuper.description,whichreturnstheVehicleclass’sdescriptionproperty.TheCarclass’sversionofdescriptionthenaddssomeextratextontotheendofthisdescriptiontoprovideinformationaboutthecurrentgear.

IfyoucreateaninstanceoftheCarclassandsetitsgearandcurrentSpeedproperties,youcanseethatitsdescriptionpropertyreturnsthetailoreddescriptiondefinedwithintheCarclass:

1 letcar=Car()

2 car.currentSpeed=25.0

Page 283: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 car.gear=3

4 print("Car:\(car.description)")

5 //Car:travelingat25.0milesperhouringear3

OverridingPropertyObservers

Youcanusepropertyoverridingtoaddpropertyobserverstoaninheritedproperty.Thisenablesyoutobenotifiedwhenthevalueofaninheritedpropertychanges,regardlessofhowthatpropertywasoriginallyimplemented.Formoreinformationonpropertyobservers,seePropertyObservers.

NOTE

Youcannotaddpropertyobserverstoinheritedconstantstoredpropertiesorinheritedread-onlycomputedproperties.Thevalueofthesepropertiescannotbeset,andsoitisnotappropriatetoprovideawillSetordidSetimplementationaspartofanoverride.

Notealsothatyoucannotprovidebothanoverridingsetterandanoverridingpropertyobserverforthesameproperty.Ifyouwanttoobservechangestoaproperty’svalue,andyouarealreadyprovidingacustomsetterforthatproperty,youcansimplyobserveanyvaluechangesfromwithinthecustomsetter.

ThefollowingexampledefinesanewclasscalledAutomaticCar,whichisasubclassofCar.TheAutomaticCarclassrepresentsacarwithanautomaticgearbox,whichautomaticallyselectsanappropriategeartousebasedonthecurrentspeed:

1 classAutomaticCar:Car{

2 overridevarcurrentSpeed:Double{

3 didSet{

4 gear=Int(currentSpeed/10.0)+1

5 }

6 }

7 }

WheneveryousetthecurrentSpeedpropertyofanAutomaticCarinstance,theproperty’sdidSetobserversetstheinstance’sgearpropertytoanappropriate

Page 284: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

choiceofgearforthenewspeed.Specifically,thepropertyobserverchoosesagearthatisthenewcurrentSpeedvaluedividedby10,roundeddowntothenearestinteger,plus1.Aspeedof35.0producesagearof4:

1 letautomatic=AutomaticCar()

2 automatic.currentSpeed=35.0

3 print("AutomaticCar:\(automatic.description)")

4 //AutomaticCar:travelingat35.0milesperhouringear4

PreventingOverrides

Youcanpreventamethod,property,orsubscriptfrombeingoverriddenbymarkingitasfinal.Dothisbywritingthefinalmodifierbeforethemethod,property,orsubscript’sintroducerkeyword(suchasfinalvar,finalfunc,finalclassfunc,andfinalsubscript).

Anyattempttooverrideafinalmethod,property,orsubscriptinasubclassisreportedasacompile-timeerror.Methods,properties,orsubscriptsthatyouaddtoaclassinanextensioncanalsobemarkedasfinalwithintheextension’sdefinition.

Youcanmarkanentireclassasfinalbywritingthefinalmodifierbeforetheclasskeywordinitsclassdefinition(finalclass).Anyattempttosubclassafinalclassisreportedasacompile-timeerror.

Page 285: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Initialization

Initializationistheprocessofpreparinganinstanceofaclass,structure,orenumerationforuse.Thisprocessinvolvessettinganinitialvalueforeachstoredpropertyonthatinstanceandperforminganyothersetuporinitializationthatisrequiredbeforethenewinstanceisreadyforuse.

Youimplementthisinitializationprocessbydefininginitializers,whicharelikespecialmethodsthatcanbecalledtocreateanewinstanceofaparticulartype.UnlikeObjective-Cinitializers,Swiftinitializersdonotreturnavalue.Theirprimaryroleistoensurethatnewinstancesofatypearecorrectlyinitializedbeforetheyareusedforthefirsttime.

Instancesofclasstypescanalsoimplementadeinitializer,whichperformsanycustomcleanupjustbeforeaninstanceofthatclassisdeallocated.Formoreinformationaboutdeinitializers,seeDeinitialization.

SettingInitialValuesforStoredProperties

Classesandstructuresmustsetalloftheirstoredpropertiestoanappropriateinitialvaluebythetimeaninstanceofthatclassorstructureiscreated.Storedpropertiescannotbeleftinanindeterminatestate.

Youcansetaninitialvalueforastoredpropertywithinaninitializer,orbyassigningadefaultpropertyvalueaspartoftheproperty’sdefinition.Theseactionsaredescribedinthefollowingsections.

NOTE

Whenyouassignadefaultvaluetoastoredproperty,orsetitsinitialvaluewithinaninitializer,thevalueofthatpropertyissetdirectly,withoutcallinganypropertyobservers.

Page 286: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

InitializersInitializersarecalledtocreateanewinstanceofaparticulartype.Initssimplestform,aninitializerislikeaninstancemethodwithnoparameters,writtenusingtheinitkeyword:

1 init(){

2 //performsomeinitializationhere

3 }

TheexamplebelowdefinesanewstructurecalledFahrenheittostoretemperaturesexpressedintheFahrenheitscale.TheFahrenheitstructurehasonestoredproperty,temperature,whichisoftypeDouble:

1 structFahrenheit{

2 vartemperature:Double

3 init(){

4 temperature=32.0

5 }

6 }

7 varf=Fahrenheit()

8 print("Thedefaulttemperatureis\(f.temperature)°

Fahrenheit")

9 //Prints"Thedefaulttemperatureis32.0°Fahrenheit"

Thestructuredefinesasingleinitializer,init,withnoparameters,whichinitializesthestoredtemperaturewithavalueof32.0(thefreezingpointofwaterindegreesFahrenheit).

DefaultPropertyValuesYoucansettheinitialvalueofastoredpropertyfromwithinaninitializer,asshownabove.Alternatively,specifyadefaultpropertyvalueaspartoftheproperty’sdeclaration.Youspecifyadefaultpropertyvaluebyassigningan

Page 287: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

initialvaluetothepropertywhenitisdefined.

NOTE

Ifapropertyalwaystakesthesameinitialvalue,provideadefaultvalueratherthansettingavaluewithinaninitializer.Theendresultisthesame,butthedefaultvaluetiestheproperty’sinitializationmorecloselytoitsdeclaration.Itmakesforshorter,clearerinitializersandenablesyoutoinferthetypeofthepropertyfromitsdefaultvalue.Thedefaultvaluealsomakesiteasierforyoutotakeadvantageofdefaultinitializersandinitializerinheritance,asdescribedlaterinthischapter.

YoucanwritetheFahrenheitstructurefromaboveinasimplerformbyprovidingadefaultvalueforitstemperaturepropertyatthepointthatthepropertyisdeclared:

1 structFahrenheit{

2 vartemperature=32.0

3 }

CustomizingInitialization

Youcancustomizetheinitializationprocesswithinputparametersandoptionalpropertytypes,orbyassigningconstantpropertiesduringinitialization,asdescribedinthefollowingsections.

InitializationParametersYoucanprovideinitializationparametersaspartofaninitializer’sdefinition,todefinethetypesandnamesofvaluesthatcustomizetheinitializationprocess.Initializationparametershavethesamecapabilitiesandsyntaxasfunctionandmethodparameters.

ThefollowingexampledefinesastructurecalledCelsius,whichstorestemperaturesexpressedindegreesCelsius.TheCelsiusstructureimplementstwocustominitializerscalledinit(fromFahrenheit:)andinit(fromKelvin:),whichinitializeanewinstanceofthestructurewithavaluefromadifferent

Page 288: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

temperaturescale:

1 structCelsius{

2 vartemperatureInCelsius:Double

3 init(fromFahrenheitfahrenheit:Double){

4 temperatureInCelsius=(fahrenheit-32.0)/1.8

5 }

6 init(fromKelvinkelvin:Double){

7 temperatureInCelsius=kelvin-273.15

8 }

9 }

10 letboilingPointOfWater=Celsius(fromFahrenheit:212.0)

11 //boilingPointOfWater.temperatureInCelsiusis100.0

12 letfreezingPointOfWater=Celsius(fromKelvin:273.15)

13 //freezingPointOfWater.temperatureInCelsiusis0.0

ThefirstinitializerhasasingleinitializationparameterwithanargumentlabeloffromFahrenheitandaparameternameoffahrenheit.ThesecondinitializerhasasingleinitializationparameterwithanargumentlabeloffromKelvinandaparameternameofkelvin.BothinitializersconverttheirsingleargumentintothecorrespondingCelsiusvalueandstorethisvalueinapropertycalledtemperatureInCelsius.

ParameterNamesandArgumentLabelsAswithfunctionandmethodparameters,initializationparameterscanhavebothaparameternameforusewithintheinitializer’sbodyandanargumentlabelforusewhencallingtheinitializer.

However,initializersdonothaveanidentifyingfunctionnamebeforetheirparenthesesinthewaythatfunctionsandmethodsdo.Therefore,thenamesandtypesofaninitializer’sparametersplayaparticularlyimportantroleinidentifyingwhichinitializershouldbecalled.Becauseofthis,Swiftprovidesan

Page 289: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

automaticargumentlabelforeveryparameterinaninitializerifyoudon’tprovideone.

ThefollowingexampledefinesastructurecalledColor,withthreeconstantpropertiescalledred,green,andblue.Thesepropertiesstoreavaluebetween0.0and1.0toindicatetheamountofred,green,andblueinthecolor.

ColorprovidesaninitializerwiththreeappropriatelynamedparametersoftypeDoubleforitsred,green,andbluecomponents.Coloralsoprovidesasecondinitializerwithasinglewhiteparameter,whichisusedtoprovidethesamevalueforallthreecolorcomponents.

1 structColor{

2 letred,green,blue:Double

3 init(red:Double,green:Double,blue:Double){

4 self.red=red

5 self.green=green

6 self.blue=blue

7 }

8 init(white:Double){

9 red=white

10 green=white

11 blue=white

12 }

13 }

BothinitializerscanbeusedtocreateanewColorinstance,byprovidingnamedvaluesforeachinitializerparameter:

1 letmagenta=Color(red:1.0,green:0.0,blue:1.0)

2 lethalfGray=Color(white:0.5)

Notethatitisnotpossibletocalltheseinitializerswithoutusingargumentlabels.Argumentlabelsmustalwaysbeusedinaninitializeriftheyaredefined,

Page 290: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

andomittingthemisacompile-timeerror:

1 letveryGreen=Color(0.0,1.0,0.0)

2 //thisreportsacompile-timeerror-argumentlabelsare

required

InitializerParametersWithoutArgumentLabelsIfyoudonotwanttouseanargumentlabelforaninitializerparameter,writeanunderscore(_)insteadofanexplicitargumentlabelforthatparametertooverridethedefaultbehavior.

Here’sanexpandedversionoftheCelsiusexamplefromInitializationParametersabove,withanadditionalinitializertocreateanewCelsiusinstancefromaDoublevaluethatisalreadyintheCelsiusscale:

1 structCelsius{

2 vartemperatureInCelsius:Double

3 init(fromFahrenheitfahrenheit:Double){

4 temperatureInCelsius=(fahrenheit-32.0)/1.8

5 }

6 init(fromKelvinkelvin:Double){

7 temperatureInCelsius=kelvin-273.15

8 }

9 init(_celsius:Double){

10 temperatureInCelsius=celsius

11 }

12 }

13 letbodyTemperature=Celsius(37.0)

14 //bodyTemperature.temperatureInCelsiusis37.0

TheinitializercallCelsius(37.0)isclearinitsintentwithouttheneedforan

Page 291: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

argumentlabel.Itisthereforeappropriatetowritethisinitializerasinit(_celsius:Double)sothatitcanbecalledbyprovidinganunnamedDoublevalue.

OptionalPropertyTypesIfyourcustomtypehasastoredpropertythatislogicallyallowedtohave“novalue”—perhapsbecauseitsvaluecannotbesetduringinitialization,orbecauseitisallowedtohave“novalue”atsomelaterpoint—declarethepropertywithanoptionaltype.Propertiesofoptionaltypeareautomaticallyinitializedwithavalueofnil,indicatingthatthepropertyisdeliberatelyintendedtohave“novalueyet”duringinitialization.

ThefollowingexampledefinesaclasscalledSurveyQuestion,withanoptionalStringpropertycalledresponse:

1 classSurveyQuestion{

2 vartext:String

3 varresponse:String?

4 init(text:String){

5 self.text=text

6 }

7 funcask(){

8 print(text)

9 }

10 }

11 letcheeseQuestion=SurveyQuestion(text:"Doyoulike

cheese?")

12 cheeseQuestion.ask()

13 //Prints"Doyoulikecheese?"

14 cheeseQuestion.response="Yes,Idolikecheese."

Theresponsetoasurveyquestioncannotbeknownuntilitisasked,andsotheresponsepropertyisdeclaredwithatypeofString?,or“optionalString”.Itis

Page 292: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

automaticallyassignedadefaultvalueofnil,meaning“nostringyet”,whenanewinstanceofSurveyQuestionisinitialized.

AssigningConstantPropertiesDuringInitializationYoucanassignavaluetoaconstantpropertyatanypointduringinitialization,aslongasitissettoadefinitevaluebythetimeinitializationfinishes.Onceaconstantpropertyisassignedavalue,itcan’tbefurthermodified.

NOTE

Forclassinstances,aconstantpropertycanbemodifiedduringinitializationonlybytheclassthatintroducesit.Itcannotbemodifiedbyasubclass.

YoucanrevisetheSurveyQuestionexamplefromabovetouseaconstantpropertyratherthanavariablepropertyforthetextpropertyofthequestion,toindicatethatthequestiondoesnotchangeonceaninstanceofSurveyQuestioniscreated.Eventhoughthetextpropertyisnowaconstant,itcanstillbesetwithintheclass’sinitializer:

1 classSurveyQuestion{

2 lettext:String

3 varresponse:String?

4 init(text:String){

5 self.text=text

6 }

7 funcask(){

8 print(text)

9 }

10 }

11 letbeetsQuestion=SurveyQuestion(text:"Howaboutbeets?")

12 beetsQuestion.ask()

13 //Prints"Howaboutbeets?"

Page 293: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

14 beetsQuestion.response="Ialsolikebeets.(Butnotwith

cheese.)"

DefaultInitializers

Swiftprovidesadefaultinitializerforanystructureorclassthatprovidesdefaultvaluesforallofitspropertiesanddoesnotprovideatleastoneinitializeritself.Thedefaultinitializersimplycreatesanewinstancewithallofitspropertiessettotheirdefaultvalues.

ThisexampledefinesaclasscalledShoppingListItem,whichencapsulatesthename,quantity,andpurchasestateofaniteminashoppinglist:

1 classShoppingListItem{

2 varname:String?

3 varquantity=1

4 varpurchased=false

5 }

6 varitem=ShoppingListItem()

BecauseallpropertiesoftheShoppingListItemclasshavedefaultvalues,andbecauseitisabaseclasswithnosuperclass,ShoppingListItemautomaticallygainsadefaultinitializerimplementationthatcreatesanewinstancewithallofitspropertiessettotheirdefaultvalues.(ThenamepropertyisanoptionalStringproperty,andsoitautomaticallyreceivesadefaultvalueofnil,eventhoughthisvalueisnotwritteninthecode.)TheexampleaboveusesthedefaultinitializerfortheShoppingListItemclasstocreateanewinstanceoftheclasswithinitializersyntax,writtenasShoppingListItem(),andassignsthisnewinstancetoavariablecalleditem.

MemberwiseInitializersforStructureTypes

Page 294: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Structuretypesautomaticallyreceiveamemberwiseinitializeriftheydon’tdefineanyoftheirowncustominitializers.Unlikeadefaultinitializer,thestructurereceivesamemberwiseinitializerevenifithasstoredpropertiesthatdon’thavedefaultvalues.

Thememberwiseinitializerisashorthandwaytoinitializethememberpropertiesofnewstructureinstances.Initialvaluesforthepropertiesofthenewinstancecanbepassedtothememberwiseinitializerbyname.

TheexamplebelowdefinesastructurecalledSizewithtwopropertiescalledwidthandheight.BothpropertiesareinferredtobeoftypeDoublebyassigningadefaultvalueof0.0.

TheSizestructureautomaticallyreceivesaninit(width:height:)memberwiseinitializer,whichyoucanusetoinitializeanewSizeinstance:

1 structSize{

2 varwidth=0.0,height=0.0

3 }

4 lettwoByTwo=Size(width:2.0,height:2.0)

Whenyoucallamemberwiseinitializer,youcanomitvaluesforanypropertiesthathavedefaultvalues.Intheexampleabove,theSizestructurehasadefaultvalueforbothitsheightandwidthproperties.Youcanomiteitherpropertyorbothproperties,andtheinitializerusesthedefaultvalueforanythingyouomit—forexample:

1 letzeroByTwo=Size(height:2.0)

2 print(zeroByTwo.width,zeroByTwo.height)

3 //Prints"0.02.0"

4

5 letzeroByZero=Size()

6 print(zeroByZero.width,zeroByZero.height)

7 //Prints"0.00.0"

Page 295: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

InitializerDelegationforValueTypes

Initializerscancallotherinitializerstoperformpartofaninstance’sinitialization.Thisprocess,knownasinitializerdelegation,avoidsduplicatingcodeacrossmultipleinitializers.

Therulesforhowinitializerdelegationworks,andforwhatformsofdelegationareallowed,aredifferentforvaluetypesandclasstypes.Valuetypes(structuresandenumerations)donotsupportinheritance,andsotheirinitializerdelegationprocessisrelativelysimple,becausetheycanonlydelegatetoanotherinitializerthattheyprovidethemselves.Classes,however,caninheritfromotherclasses,asdescribedinInheritance.Thismeansthatclasseshaveadditionalresponsibilitiesforensuringthatallstoredpropertiestheyinheritareassignedasuitablevalueduringinitialization.TheseresponsibilitiesaredescribedinClassInheritanceandInitializationbelow.

Forvaluetypes,youuseself.inittorefertootherinitializersfromthesamevaluetypewhenwritingyourowncustominitializers.Youcancallself.initonlyfromwithinaninitializer.

Notethatifyoudefineacustominitializerforavaluetype,youwillnolongerhaveaccesstothedefaultinitializer(orthememberwiseinitializer,ifitisastructure)forthattype.Thisconstraintpreventsasituationinwhichadditionalessentialsetupprovidedinamorecomplexinitializerisaccidentallycircumventedbysomeoneusingoneoftheautomaticinitializers.

NOTE

Ifyouwantyourcustomvaluetypetobeinitializablewiththedefaultinitializerandmemberwiseinitializer,andalsowithyourowncustominitializers,writeyourcustominitializersinanextensionratherthanaspartofthevaluetype’soriginalimplementation.Formoreinformation,seeExtensions.

ThefollowingexampledefinesacustomRectstructuretorepresentageometricrectangle.TheexamplerequirestwosupportingstructurescalledSizeandPoint,bothofwhichprovidedefaultvaluesof0.0foralloftheirproperties:

1 structSize{

2 varwidth=0.0,height=0.0

Page 296: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 }

4 structPoint{

5 varx=0.0,y=0.0

6 }

YoucaninitializetheRectstructurebelowinoneofthreeways—byusingitsdefaultzero-initializedoriginandsizepropertyvalues,byprovidingaspecificoriginpointandsize,orbyprovidingaspecificcenterpointandsize.TheseinitializationoptionsarerepresentedbythreecustominitializersthatarepartoftheRectstructure’sdefinition:

1 structRect{

2 varorigin=Point()

3 varsize=Size()

4 init(){}

5 init(origin:Point,size:Size){

6 self.origin=origin

7 self.size=size

8 }

9 init(center:Point,size:Size){

10 letoriginX=center.x-(size.width/2)

11 letoriginY=center.y-(size.height/2)

12 self.init(origin:Point(x:originX,y:originY),size:

size)

13 }

14 }

ThefirstRectinitializer,init(),isfunctionallythesameasthedefaultinitializerthatthestructurewouldhavereceivedifitdidnothaveitsowncustominitializers.Thisinitializerhasanemptybody,representedbyanemptypairofcurlybraces{}.CallingthisinitializerreturnsaRectinstancewhoseoriginandsizepropertiesarebothinitializedwiththedefaultvaluesofPoint(x:0.0,y:

Page 297: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

0.0)andSize(width:0.0,height:0.0)fromtheirpropertydefinitions:

1 letbasicRect=Rect()

2 //basicRect'soriginis(0.0,0.0)anditssizeis(0.0,0.0)

ThesecondRectinitializer,init(origin:size:),isfunctionallythesameasthememberwiseinitializerthatthestructurewouldhavereceivedifitdidnothaveitsowncustominitializers.Thisinitializersimplyassignstheoriginandsizeargumentvaluestotheappropriatestoredproperties:

1 letoriginRect=Rect(origin:Point(x:2.0,y:2.0),

2 size:Size(width:5.0,height:5.0))

3 //originRect'soriginis(2.0,2.0)anditssizeis(5.0,5.0)

ThethirdRectinitializer,init(center:size:),isslightlymorecomplex.Itstartsbycalculatinganappropriateoriginpointbasedonacenterpointandasizevalue.Itthencalls(ordelegates)totheinit(origin:size:)initializer,whichstorestheneworiginandsizevaluesintheappropriateproperties:

1 letcenterRect=Rect(center:Point(x:4.0,y:4.0),

2 size:Size(width:3.0,height:3.0))

3 //centerRect'soriginis(2.5,2.5)anditssizeis(3.0,3.0)

Theinit(center:size:)initializercouldhaveassignedthenewvaluesoforiginandsizetotheappropriatepropertiesitself.However,itismoreconvenient(andclearerinintent)fortheinit(center:size:)initializertotakeadvantageofanexistinginitializerthatalreadyprovidesexactlythatfunctionality.

NOTE

Foranalternativewaytowritethisexamplewithoutdefiningtheinit()andinit(origin:size:)initializersyourself,seeExtensions.

Page 298: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ClassInheritanceandInitialization

Allofaclass’sstoredproperties—includinganypropertiestheclassinheritsfromitssuperclass—mustbeassignedaninitialvalueduringinitialization.

Swiftdefinestwokindsofinitializersforclasstypestohelpensureallstoredpropertiesreceiveaninitialvalue.Theseareknownasdesignatedinitializersandconvenienceinitializers.

DesignatedInitializersandConvenienceInitializersDesignatedinitializersaretheprimaryinitializersforaclass.Adesignatedinitializerfullyinitializesallpropertiesintroducedbythatclassandcallsanappropriatesuperclassinitializertocontinuetheinitializationprocessupthesuperclasschain.

Classestendtohaveveryfewdesignatedinitializers,anditisquitecommonforaclasstohaveonlyone.Designatedinitializersare“funnel”pointsthroughwhichinitializationtakesplace,andthroughwhichtheinitializationprocesscontinuesupthesuperclasschain.

Everyclassmusthaveatleastonedesignatedinitializer.Insomecases,thisrequirementissatisfiedbyinheritingoneormoredesignatedinitializersfromasuperclass,asdescribedinAutomaticInitializerInheritancebelow.

Convenienceinitializersaresecondary,supportinginitializersforaclass.Youcandefineaconvenienceinitializertocalladesignatedinitializerfromthesameclassastheconvenienceinitializerwithsomeofthedesignatedinitializer’sparameterssettodefaultvalues.Youcanalsodefineaconvenienceinitializertocreateaninstanceofthatclassforaspecificusecaseorinputvaluetype.

Youdonothavetoprovideconvenienceinitializersifyourclassdoesnotrequirethem.Createconvenienceinitializerswheneverashortcuttoacommoninitializationpatternwillsavetimeormakeinitializationoftheclassclearerinintent.

Page 299: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

SyntaxforDesignatedandConvenienceInitializersDesignatedinitializersforclassesarewritteninthesamewayassimpleinitializersforvaluetypes:

init( parameters ){

statements

}

Convenienceinitializersarewritteninthesamestyle,butwiththeconveniencemodifierplacedbeforetheinitkeyword,separatedbyaspace:

convenienceinit( parameters ){

statements

}

InitializerDelegationforClassTypesTosimplifytherelationshipsbetweendesignatedandconvenienceinitializers,Swiftappliesthefollowingthreerulesfordelegationcallsbetweeninitializers:

Rule1

Adesignatedinitializermustcalladesignatedinitializerfromitsimmediatesuperclass.

Rule2

Aconvenienceinitializermustcallanotherinitializerfromthesameclass.

Rule3

Aconvenienceinitializermustultimatelycalladesignatedinitializer.

Asimplewaytorememberthisis:

Designatedinitializersmustalwaysdelegateup.

Page 300: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Convenienceinitializersmustalwaysdelegateacross.

Theserulesareillustratedinthefigurebelow:

Here,thesuperclasshasasingledesignatedinitializerandtwoconvenienceinitializers.Oneconvenienceinitializercallsanotherconvenienceinitializer,whichinturncallsthesingledesignatedinitializer.Thissatisfiesrules2and3fromabove.Thesuperclassdoesnotitselfhaveafurthersuperclass,andsorule1doesnotapply.

Thesubclassinthisfigurehastwodesignatedinitializersandoneconvenienceinitializer.Theconvenienceinitializermustcalloneofthetwodesignatedinitializers,becauseitcanonlycallanotherinitializerfromthesameclass.Thissatisfiesrules2and3fromabove.Bothdesignatedinitializersmustcallthesingledesignatedinitializerfromthesuperclass,tosatisfyrule1fromabove.

NOTE

Theserulesdon’taffecthowusersofyourclassescreateinstancesofeachclass.Anyinitializerinthediagramabovecanbeusedtocreateafullyinitializedinstanceoftheclasstheybelongto.Therulesonlyaffecthowyouwritetheimplementationoftheclass’sinitializers.

Thefigurebelowshowsamorecomplexclasshierarchyforfourclasses.Itillustrateshowthedesignatedinitializersinthishierarchyactas“funnel”pointsforclassinitialization,simplifyingtheinterrelationshipsamongclassesinthechain:

Page 301: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Two-PhaseInitializationClassinitializationinSwiftisatwo-phaseprocess.Inthefirstphase,eachstoredpropertyisassignedaninitialvaluebytheclassthatintroducedit.Oncetheinitialstateforeverystoredpropertyhasbeendetermined,thesecondphasebegins,andeachclassisgiventheopportunitytocustomizeitsstoredpropertiesfurtherbeforethenewinstanceisconsideredreadyforuse.

Theuseofatwo-phaseinitializationprocessmakesinitializationsafe,whilestillgivingcompleteflexibilitytoeachclassinaclasshierarchy.Two-phaseinitializationpreventspropertyvaluesfrombeingaccessedbeforetheyareinitialized,andpreventspropertyvaluesfrombeingsettoadifferentvaluebyanotherinitializerunexpectedly.

NOTE

Swift’stwo-phaseinitializationprocessissimilartoinitializationinObjective-C.Themaindifferenceisthatduringphase1,Objective-Cassignszeroornullvalues(suchas0ornil)toevery

Page 302: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

property.Swift’sinitializationflowismoreflexibleinthatitletsyousetcustominitialvalues,andcancopewithtypesforwhich0ornilisnotavaliddefaultvalue.

Swift’scompilerperformsfourhelpfulsafety-checkstomakesurethattwo-phaseinitializationiscompletedwithouterror:

Safetycheck1

Adesignatedinitializermustensurethatallofthepropertiesintroducedbyitsclassareinitializedbeforeitdelegatesuptoasuperclassinitializer.

Asmentionedabove,thememoryforanobjectisonlyconsideredfullyinitializedoncetheinitialstateofallofitsstoredpropertiesisknown.Inorderforthisruletobesatisfied,adesignatedinitializermustmakesurethatallofitsownpropertiesareinitializedbeforeithandsoffupthechain.

Safetycheck2

Adesignatedinitializermustdelegateuptoasuperclassinitializerbeforeassigningavaluetoaninheritedproperty.Ifitdoesn’t,thenewvaluethedesignatedinitializerassignswillbeoverwrittenbythesuperclassaspartofitsowninitialization.

Safetycheck3

Aconvenienceinitializermustdelegatetoanotherinitializerbeforeassigningavaluetoanyproperty(includingpropertiesdefinedbythesameclass).Ifitdoesn’t,thenewvaluetheconvenienceinitializerassignswillbeoverwrittenbyitsownclass’sdesignatedinitializer.

Safetycheck4

Aninitializercannotcallanyinstancemethods,readthevaluesofanyinstanceproperties,orrefertoselfasavalueuntilafterthefirstphaseofinitializationiscomplete.

Theclassinstanceisnotfullyvaliduntilthefirstphaseends.Propertiescanonlybeaccessed,andmethodscanonlybecalled,oncetheclassinstanceisknowntobevalidattheendofthefirstphase.

Page 303: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Here’showtwo-phaseinitializationplaysout,basedonthefoursafetychecksabove:

Phase1

Adesignatedorconvenienceinitializeriscalledonaclass.

Memoryforanewinstanceofthatclassisallocated.Thememoryisnotyetinitialized.

Adesignatedinitializerforthatclassconfirmsthatallstoredpropertiesintroducedbythatclasshaveavalue.Thememoryforthesestoredpropertiesisnowinitialized.

Thedesignatedinitializerhandsofftoasuperclassinitializertoperformthesametaskforitsownstoredproperties.

Thiscontinuesuptheclassinheritancechainuntilthetopofthechainisreached.

Oncethetopofthechainisreached,andthefinalclassinthechainhasensuredthatallofitsstoredpropertieshaveavalue,theinstance’smemoryisconsideredtobefullyinitialized,andphase1iscomplete.

Phase2

Workingbackdownfromthetopofthechain,eachdesignatedinitializerinthechainhastheoptiontocustomizetheinstancefurther.Initializersarenowabletoaccessselfandcanmodifyitsproperties,callitsinstancemethods,andsoon.

Finally,anyconvenienceinitializersinthechainhavetheoptiontocustomizetheinstanceandtoworkwithself.

Here’showphase1looksforaninitializationcallforahypotheticalsubclassandsuperclass:

Page 304: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Inthisexample,initializationbeginswithacalltoaconvenienceinitializeronthesubclass.Thisconvenienceinitializercannotyetmodifyanyproperties.Itdelegatesacrosstoadesignatedinitializerfromthesameclass.

Thedesignatedinitializermakessurethatallofthesubclass’spropertieshaveavalue,aspersafetycheck1.Itthencallsadesignatedinitializeronitssuperclasstocontinuetheinitializationupthechain.

Thesuperclass’sdesignatedinitializermakessurethatallofthesuperclasspropertieshaveavalue.Therearenofurthersuperclassestoinitialize,andsonofurtherdelegationisneeded.

Assoonasallpropertiesofthesuperclasshaveaninitialvalue,itsmemoryisconsideredfullyinitialized,andphase1iscomplete.

Here’showphase2looksforthesameinitializationcall:

Thesuperclass’sdesignatedinitializernowhasanopportunitytocustomizethe

Page 305: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

instancefurther(althoughitdoesnothaveto).

Oncethesuperclass’sdesignatedinitializerisfinished,thesubclass’sdesignatedinitializercanperformadditionalcustomization(althoughagain,itdoesnothaveto).

Finally,oncethesubclass’sdesignatedinitializerisfinished,theconvenienceinitializerthatwasoriginallycalledcanperformadditionalcustomization.

InitializerInheritanceandOverridingUnlikesubclassesinObjective-C,Swiftsubclassesdonotinherittheirsuperclassinitializersbydefault.Swift’sapproachpreventsasituationinwhichasimpleinitializerfromasuperclassisinheritedbyamorespecializedsubclassandisusedtocreateanewinstanceofthesubclassthatisnotfullyorcorrectlyinitialized.

NOTE

Superclassinitializersareinheritedincertaincircumstances,butonlywhenitissafeandappropriatetodoso.Formoreinformation,seeAutomaticInitializerInheritancebelow.

Ifyouwantacustomsubclasstopresentoneormoreofthesameinitializersasitssuperclass,youcanprovideacustomimplementationofthoseinitializerswithinthesubclass.

Whenyouwriteasubclassinitializerthatmatchesasuperclassdesignatedinitializer,youareeffectivelyprovidinganoverrideofthatdesignatedinitializer.Therefore,youmustwritetheoverridemodifierbeforethesubclass’sinitializerdefinition.Thisistrueevenifyouareoverridinganautomaticallyprovideddefaultinitializer,asdescribedinDefaultInitializers.

Aswithanoverriddenproperty,methodorsubscript,thepresenceoftheoverridemodifierpromptsSwifttocheckthatthesuperclasshasamatchingdesignatedinitializertobeoverridden,andvalidatesthattheparametersforyouroverridinginitializerhavebeenspecifiedasintended.

Page 306: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Youalwayswritetheoverridemodifierwhenoverridingasuperclassdesignatedinitializer,evenifyoursubclass’simplementationoftheinitializerisaconvenienceinitializer.

Conversely,ifyouwriteasubclassinitializerthatmatchesasuperclassconvenienceinitializer,thatsuperclassconvenienceinitializercanneverbecalleddirectlybyyoursubclass,aspertherulesdescribedaboveinInitializerDelegationforClassTypes.Therefore,yoursubclassisnot(strictlyspeaking)providinganoverrideofthesuperclassinitializer.Asaresult,youdonotwritetheoverridemodifierwhenprovidingamatchingimplementationofasuperclassconvenienceinitializer.

TheexamplebelowdefinesabaseclasscalledVehicle.ThisbaseclassdeclaresastoredpropertycallednumberOfWheels,withadefaultIntvalueof0.ThenumberOfWheelspropertyisusedbyacomputedpropertycalleddescriptiontocreateaStringdescriptionofthevehicle’scharacteristics:

1 classVehicle{

2 varnumberOfWheels=0

3 vardescription:String{

4 return"\(numberOfWheels)wheel(s)"

5 }

6 }

TheVehicleclassprovidesadefaultvalueforitsonlystoredproperty,anddoesnotprovideanycustominitializersitself.Asaresult,itautomaticallyreceivesadefaultinitializer,asdescribedinDefaultInitializers.Thedefaultinitializer(whenavailable)isalwaysadesignatedinitializerforaclass,andcanbeusedtocreateanewVehicleinstancewithanumberOfWheelsof0:

1 letvehicle=Vehicle()

2 print("Vehicle:\(vehicle.description)")

3 //Vehicle:0wheel(s)

Page 307: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThenextexampledefinesasubclassofVehiclecalledBicycle:

1 classBicycle:Vehicle{

2 overrideinit(){

3 super.init()

4 numberOfWheels=2

5 }

6 }

TheBicyclesubclassdefinesacustomdesignatedinitializer,init().ThisdesignatedinitializermatchesadesignatedinitializerfromthesuperclassofBicycle,andsotheBicycleversionofthisinitializerismarkedwiththeoverridemodifier.

Theinit()initializerforBicyclestartsbycallingsuper.init(),whichcallsthedefaultinitializerfortheBicycleclass’ssuperclass,Vehicle.ThisensuresthatthenumberOfWheelsinheritedpropertyisinitializedbyVehiclebeforeBicyclehastheopportunitytomodifytheproperty.Aftercallingsuper.init(),theoriginalvalueofnumberOfWheelsisreplacedwithanewvalueof2.

IfyoucreateaninstanceofBicycle,youcancallitsinheriteddescriptioncomputedpropertytoseehowitsnumberOfWheelspropertyhasbeenupdated:

1 letbicycle=Bicycle()

2 print("Bicycle:\(bicycle.description)")

3 //Bicycle:2wheel(s)

Ifasubclassinitializerperformsnocustomizationinphase2oftheinitializationprocess,andthesuperclasshasazero-argumentdesignatedinitializer,youcanomitacalltosuper.init()afterassigningvaluestoallofthesubclass’sstoredproperties.

ThisexampledefinesanothersubclassofVehicle,calledHoverboard.Initsinitializer,theHoverboardclasssetsonlyitscolorproperty.Insteadofmakinganexplicitcalltosuper.init(),thisinitializerreliesonanimplicitcalltoits

Page 308: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

superclass’sinitializertocompletetheprocess.

1 classHoverboard:Vehicle{

2 varcolor:String

3 init(color:String){

4 self.color=color

5 //super.init()implicitlycalledhere

6 }

7 overridevardescription:String{

8 return"\(super.description)inabeautiful\(color)"

9 }

10 }

AninstanceofHoverboardusesthedefaultnumberofwheelssuppliedbytheVehicleinitializer.

1 lethoverboard=Hoverboard(color:"silver")

2 print("Hoverboard:\(hoverboard.description)")

3 //Hoverboard:0wheel(s)inabeautifulsilver

NOTE

Subclassescanmodifyinheritedvariablepropertiesduringinitialization,butcannotmodifyinheritedconstantproperties.

AutomaticInitializerInheritanceAsmentionedabove,subclassesdonotinherittheirsuperclassinitializersbydefault.However,superclassinitializersareautomaticallyinheritedifcertainconditionsaremet.Inpractice,thismeansthatyoudonotneedtowriteinitializeroverridesinmanycommonscenarios,andcaninherityoursuperclassinitializerswithminimaleffortwheneveritissafetodoso.

Assumingthatyouprovidedefaultvaluesforanynewpropertiesyouintroduce

Page 309: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

inasubclass,thefollowingtworulesapply:

Rule1

Ifyoursubclassdoesn’tdefineanydesignatedinitializers,itautomaticallyinheritsallofitssuperclassdesignatedinitializers.

Rule2

Ifyoursubclassprovidesanimplementationofallofitssuperclassdesignatedinitializers—eitherbyinheritingthemasperrule1,orbyprovidingacustomimplementationaspartofitsdefinition—thenitautomaticallyinheritsallofthesuperclassconvenienceinitializers.

Theserulesapplyevenifyoursubclassaddsfurtherconvenienceinitializers.

NOTE

Asubclasscanimplementasuperclassdesignatedinitializerasasubclassconvenienceinitializeraspartofsatisfyingrule2.

DesignatedandConvenienceInitializersinActionThefollowingexampleshowsdesignatedinitializers,convenienceinitializers,andautomaticinitializerinheritanceinaction.ThisexampledefinesahierarchyofthreeclassescalledFood,RecipeIngredient,andShoppingListItem,anddemonstrateshowtheirinitializersinteract.

ThebaseclassinthehierarchyiscalledFood,whichisasimpleclasstoencapsulatethenameofafoodstuff.TheFoodclassintroducesasingleStringpropertycallednameandprovidestwoinitializersforcreatingFoodinstances:

1 classFood{

2 varname:String

3 init(name:String){

4 self.name=name

Page 310: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 }

6 convenienceinit(){

7 self.init(name:"[Unnamed]")

8 }

9 }

ThefigurebelowshowstheinitializerchainfortheFoodclass:

Classesdonothaveadefaultmemberwiseinitializer,andsotheFoodclassprovidesadesignatedinitializerthattakesasingleargumentcalledname.ThisinitializercanbeusedtocreateanewFoodinstancewithaspecificname:

1 letnamedMeat=Food(name:"Bacon")

2 //namedMeat'snameis"Bacon"

Theinit(name:String)initializerfromtheFoodclassisprovidedasadesignatedinitializer,becauseitensuresthatallstoredpropertiesofanewFoodinstancearefullyinitialized.TheFoodclassdoesnothaveasuperclass,andsotheinit(name:String)initializerdoesnotneedtocallsuper.init()tocompleteitsinitialization.

TheFoodclassalsoprovidesaconvenienceinitializer,init(),withnoarguments.Theinit()initializerprovidesadefaultplaceholdernameforanewfoodbydelegatingacrosstotheFoodclass’sinit(name:String)withanamevalueof[Unnamed]:

1 letmysteryMeat=Food()

2 //mysteryMeat'snameis"[Unnamed]"

Page 311: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThesecondclassinthehierarchyisasubclassofFoodcalledRecipeIngredient.TheRecipeIngredientclassmodelsaningredientinacookingrecipe.ItintroducesanIntpropertycalledquantity(inadditiontothenamepropertyitinheritsfromFood)anddefinestwoinitializersforcreatingRecipeIngredientinstances:

1 classRecipeIngredient:Food{

2 varquantity:Int

3 init(name:String,quantity:Int){

4 self.quantity=quantity

5 super.init(name:name)

6 }

7 overrideconvenienceinit(name:String){

8 self.init(name:name,quantity:1)

9 }

10 }

ThefigurebelowshowstheinitializerchainfortheRecipeIngredientclass:

TheRecipeIngredientclasshasasingledesignatedinitializer,init(name:String,quantity:Int),whichcanbeusedtopopulateallofthepropertiesofanewRecipeIngredientinstance.Thisinitializerstartsbyassigningthepassed

Page 312: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

quantityargumenttothequantityproperty,whichistheonlynewpropertyintroducedbyRecipeIngredient.Afterdoingso,theinitializerdelegatesuptotheinit(name:String)initializeroftheFoodclass.Thisprocesssatisfiessafetycheck1fromTwo-PhaseInitializationabove.

RecipeIngredientalsodefinesaconvenienceinitializer,init(name:String),whichisusedtocreateaRecipeIngredientinstancebynamealone.Thisconvenienceinitializerassumesaquantityof1foranyRecipeIngredientinstancethatiscreatedwithoutanexplicitquantity.ThedefinitionofthisconvenienceinitializermakesRecipeIngredientinstancesquickerandmoreconvenienttocreate,andavoidscodeduplicationwhencreatingseveralsingle-quantityRecipeIngredientinstances.Thisconvenienceinitializersimplydelegatesacrosstotheclass’sdesignatedinitializer,passinginaquantityvalueof1.

Theinit(name:String)convenienceinitializerprovidedbyRecipeIngredienttakesthesameparametersastheinit(name:String)designatedinitializerfromFood.Becausethisconvenienceinitializeroverridesadesignatedinitializerfromitssuperclass,itmustbemarkedwiththeoverridemodifier(asdescribedinInitializerInheritanceandOverriding).

EventhoughRecipeIngredientprovidestheinit(name:String)initializerasaconvenienceinitializer,RecipeIngredienthasnonethelessprovidedanimplementationofallofitssuperclass’sdesignatedinitializers.Therefore,RecipeIngredientautomaticallyinheritsallofitssuperclass’sconvenienceinitializerstoo.

Inthisexample,thesuperclassforRecipeIngredientisFood,whichhasasingleconvenienceinitializercalledinit().ThisinitializeristhereforeinheritedbyRecipeIngredient.Theinheritedversionofinit()functionsinexactlythesamewayastheFoodversion,exceptthatitdelegatestotheRecipeIngredientversionofinit(name:String)ratherthantheFoodversion.

AllthreeoftheseinitializerscanbeusedtocreatenewRecipeIngredientinstances:

1 letoneMysteryItem=RecipeIngredient()

Page 313: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 letoneBacon=RecipeIngredient(name:"Bacon")

3 letsixEggs=RecipeIngredient(name:"Eggs",quantity:6)

ThethirdandfinalclassinthehierarchyisasubclassofRecipeIngredientcalledShoppingListItem.TheShoppingListItemclassmodelsarecipeingredientasitappearsinashoppinglist.

Everyitemintheshoppingliststartsoutas“unpurchased”.Torepresentthisfact,ShoppingListItemintroducesaBooleanpropertycalledpurchased,withadefaultvalueoffalse.ShoppingListItemalsoaddsacomputeddescriptionproperty,whichprovidesatextualdescriptionofaShoppingListIteminstance:

1 classShoppingListItem:RecipeIngredient{

2 varpurchased=false

3 vardescription:String{

4 varoutput="\(quantity)x\(name)"

5 output+=purchased?"✔":"✘"

6 returnoutput

7 }

8 }

NOTE

ShoppingListItemdoesnotdefineaninitializertoprovideaninitialvalueforpurchased,becauseitemsinashoppinglist(asmodeledhere)alwaysstartoutunpurchased.

Becauseitprovidesadefaultvalueforallofthepropertiesitintroducesanddoesnotdefineanyinitializersitself,ShoppingListItemautomaticallyinheritsallofthedesignatedandconvenienceinitializersfromitssuperclass.

Thefigurebelowshowstheoverallinitializerchainforallthreeclasses:

Page 314: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

YoucanuseallthreeoftheinheritedinitializerstocreateanewShoppingListIteminstance:

1 varbreakfastList=[

2 ShoppingListItem(),

3 ShoppingListItem(name:"Bacon"),

4 ShoppingListItem(name:"Eggs",quantity:6),

5 ]

6 breakfastList[0].name="Orangejuice"

7 breakfastList[0].purchased=true

8 foriteminbreakfastList{

9 print(item.description)

10 }

11 //1xOrangejuice✔

12 //1xBacon✘

Page 315: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

13 //6xEggs✘

Here,anewarraycalledbreakfastListiscreatedfromanarrayliteralcontainingthreenewShoppingListIteminstances.Thetypeofthearrayisinferredtobe[ShoppingListItem].Afterthearrayiscreated,thenameoftheShoppingListItematthestartofthearrayischangedfrom"[Unnamed]"to"Orangejuice"anditismarkedashavingbeenpurchased.Printingthedescriptionofeachiteminthearrayshowsthattheirdefaultstateshavebeensetasexpected.

FailableInitializers

Itissometimesusefultodefineaclass,structure,orenumerationforwhichinitializationcanfail.Thisfailuremightbetriggeredbyinvalidinitializationparametervalues,theabsenceofarequiredexternalresource,orsomeotherconditionthatpreventsinitializationfromsucceeding.

Tocopewithinitializationconditionsthatcanfail,defineoneormorefailableinitializersaspartofaclass,structure,orenumerationdefinition.Youwriteafailableinitializerbyplacingaquestionmarkaftertheinitkeyword(init?).

NOTE

Youcannotdefineafailableandanonfailableinitializerwiththesameparametertypesandnames.

Afailableinitializercreatesanoptionalvalueofthetypeitinitializes.Youwritereturnnilwithinafailableinitializertoindicateapointatwhichinitializationfailurecanbetriggered.

NOTE

Strictlyspeaking,initializersdonotreturnavalue.Rather,theirroleistoensurethatselfisfullyandcorrectlyinitializedbythetimethatinitializationends.Althoughyouwritereturnniltotriggeraninitializationfailure,youdonotusethereturnkeywordtoindicateinitializationsuccess.

Forinstance,failableinitializersareimplementedfornumerictypeconversions.

Page 316: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Toensureconversionbetweennumerictypesmaintainsthevalueexactly,usetheinit(exactly:)initializer.Ifthetypeconversioncannotmaintainthevalue,theinitializerfails.

1 letwholeNumber:Double=12345.0

2 letpi=3.14159

3

4 ifletvalueMaintained=Int(exactly:wholeNumber){

5 print("\(wholeNumber)conversiontoIntmaintainsvalueof

\(valueMaintained)")

6 }

7 //Prints"12345.0conversiontoIntmaintainsvalueof12345"

8

9 letvalueChanged=Int(exactly:pi)

10 //valueChangedisoftypeInt?,notInt

11

12 ifvalueChanged==nil{

13 print("\(pi)conversiontoIntdoesnotmaintainvalue")

14 }

15 //Prints"3.14159conversiontoIntdoesnotmaintainvalue"

TheexamplebelowdefinesastructurecalledAnimal,withaconstantStringpropertycalledspecies.TheAnimalstructurealsodefinesafailableinitializerwithasingleparametercalledspecies.Thisinitializerchecksifthespeciesvaluepassedtotheinitializerisanemptystring.Ifanemptystringisfound,aninitializationfailureistriggered.Otherwise,thespeciesproperty’svalueisset,andinitializationsucceeds:

1 structAnimal{

2 letspecies:String

3 init?(species:String){

4 ifspecies.isEmpty{returnnil}

Page 317: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 self.species=species

6 }

7 }

YoucanusethisfailableinitializertotrytoinitializeanewAnimalinstanceandtocheckifinitializationsucceeded:

1 letsomeCreature=Animal(species:"Giraffe")

2 //someCreatureisoftypeAnimal?,notAnimal

3

4 ifletgiraffe=someCreature{

5 print("Ananimalwasinitializedwithaspeciesof\

(giraffe.species)")

6 }

7 //Prints"AnanimalwasinitializedwithaspeciesofGiraffe"

Ifyoupassanemptystringvaluetothefailableinitializer’sspeciesparameter,theinitializertriggersaninitializationfailure:

1 letanonymousCreature=Animal(species:"")

2 //anonymousCreatureisoftypeAnimal?,notAnimal

3

4 ifanonymousCreature==nil{

5 print("Theanonymouscreaturecouldnotbeinitialized")

6 }

7 //Prints"Theanonymouscreaturecouldnotbeinitialized"

NOTE

Checkingforanemptystringvalue(suchas""ratherthan"Giraffe")isnotthesameascheckingforniltoindicatetheabsenceofanoptionalStringvalue.Intheexampleabove,anemptystring("")isavalid,non-optionalString.However,itisnotappropriateforananimaltohaveanemptystringasthevalueofitsspeciesproperty.Tomodelthisrestriction,thefailableinitializertriggersaninitializationfailureifanemptystringisfound.

Page 318: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

FailableInitializersforEnumerationsYoucanuseafailableinitializertoselectanappropriateenumerationcasebasedononeormoreparameters.Theinitializercanthenfailiftheprovidedparametersdonotmatchanappropriateenumerationcase.

TheexamplebelowdefinesanenumerationcalledTemperatureUnit,withthreepossiblestates(kelvin,celsius,andfahrenheit).AfailableinitializerisusedtofindanappropriateenumerationcaseforaCharactervaluerepresentingatemperaturesymbol:

1 enumTemperatureUnit{

2 casekelvin,celsius,fahrenheit

3 init?(symbol:Character){

4 switchsymbol{

5 case"K":

6 self=.kelvin

7 case"C":

8 self=.celsius

9 case"F":

10 self=.fahrenheit

11 default:

12 returnnil

13 }

14 }

15 }

Youcanusethisfailableinitializertochooseanappropriateenumerationcaseforthethreepossiblestatesandtocauseinitializationtofailiftheparameterdoesnotmatchoneofthesestates:

1 letfahrenheitUnit=TemperatureUnit(symbol:"F")

2 iffahrenheitUnit!=nil{

3 print("Thisisadefinedtemperatureunit,so

Page 319: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

initializationsucceeded.")

4 }

5 //Prints"Thisisadefinedtemperatureunit,so

initializationsucceeded."

6

7 letunknownUnit=TemperatureUnit(symbol:"X")

8 ifunknownUnit==nil{

9 print("Thisisnotadefinedtemperatureunit,so

initializationfailed.")

10 }

11 //Prints"Thisisnotadefinedtemperatureunit,so

initializationfailed."

FailableInitializersforEnumerationswithRawValuesEnumerationswithrawvaluesautomaticallyreceiveafailableinitializer,init?(rawValue:),thattakesaparametercalledrawValueoftheappropriateraw-valuetypeandselectsamatchingenumerationcaseifoneisfound,ortriggersaninitializationfailureifnomatchingvalueexists.

YoucanrewritetheTemperatureUnitexamplefromabovetouserawvaluesoftypeCharacterandtotakeadvantageoftheinit?(rawValue:)initializer:

1 enumTemperatureUnit:Character{

2 casekelvin="K",celsius="C",fahrenheit="F"

3 }

4

5 letfahrenheitUnit=TemperatureUnit(rawValue:"F")

6 iffahrenheitUnit!=nil{

7 print("Thisisadefinedtemperatureunit,so

initializationsucceeded.")

Page 320: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 }

9 //Prints"Thisisadefinedtemperatureunit,so

initializationsucceeded."

10

11 letunknownUnit=TemperatureUnit(rawValue:"X")

12 ifunknownUnit==nil{

13 print("Thisisnotadefinedtemperatureunit,so

initializationfailed.")

14 }

15 //Prints"Thisisnotadefinedtemperatureunit,so

initializationfailed."

PropagationofInitializationFailureAfailableinitializerofaclass,structure,orenumerationcandelegateacrosstoanotherfailableinitializerfromthesameclass,structure,orenumeration.Similarly,asubclassfailableinitializercandelegateuptoasuperclassfailableinitializer.

Ineithercase,ifyoudelegatetoanotherinitializerthatcausesinitializationtofail,theentireinitializationprocessfailsimmediately,andnofurtherinitializationcodeisexecuted.

NOTE

Afailableinitializercanalsodelegatetoanonfailableinitializer.Usethisapproachifyouneedtoaddapotentialfailurestatetoanexistinginitializationprocessthatdoesnototherwisefail.

TheexamplebelowdefinesasubclassofProductcalledCartItem.TheCartItemclassmodelsaniteminanonlineshoppingcart.CartItemintroducesastoredconstantpropertycalledquantityandensuresthatthispropertyalwayshasavalueofatleast1:

1 classProduct{

Page 321: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 letname:String

3 init?(name:String){

4 ifname.isEmpty{returnnil}

5 self.name=name

6 }

7 }

8

9 classCartItem:Product{

10 letquantity:Int

11 init?(name:String,quantity:Int){

12 ifquantity<1{returnnil}

13 self.quantity=quantity

14 super.init(name:name)

15 }

16 }

ThefailableinitializerforCartItemstartsbyvalidatingthatithasreceivedaquantityvalueof1ormore.Ifthequantityisinvalid,theentireinitializationprocessfailsimmediatelyandnofurtherinitializationcodeisexecuted.Likewise,thefailableinitializerforProductchecksthenamevalue,andtheinitializerprocessfailsimmediatelyifnameistheemptystring.

IfyoucreateaCartIteminstancewithanonemptynameandaquantityof1ormore,initializationsucceeds:

1 iflettwoSocks=CartItem(name:"sock",quantity:2){

2 print("Item:\(twoSocks.name),quantity:\

(twoSocks.quantity)")

3 }

4 //Prints"Item:sock,quantity:2"

IfyoutrytocreateaCartIteminstancewithaquantityvalueof0,theCartItem

Page 322: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

initializercausesinitializationtofail:

1 ifletzeroShirts=CartItem(name:"shirt",quantity:0){

2 print("Item:\(zeroShirts.name),quantity:\

(zeroShirts.quantity)")

3 }else{

4 print("Unabletoinitializezeroshirts")

5 }

6 //Prints"Unabletoinitializezeroshirts"

Similarly,ifyoutrytocreateaCartIteminstancewithanemptynamevalue,thesuperclassProductinitializercausesinitializationtofail:

1 ifletoneUnnamed=CartItem(name:"",quantity:1){

2 print("Item:\(oneUnnamed.name),quantity:\

(oneUnnamed.quantity)")

3 }else{

4 print("Unabletoinitializeoneunnamedproduct")

5 }

6 //Prints"Unabletoinitializeoneunnamedproduct"

OverridingaFailableInitializerYoucanoverrideasuperclassfailableinitializerinasubclass,justlikeanyotherinitializer.Alternatively,youcanoverrideasuperclassfailableinitializerwithasubclassnonfailableinitializer.Thisenablesyoutodefineasubclassforwhichinitializationcannotfail,eventhoughinitializationofthesuperclassisallowedtofail.

Notethatifyouoverrideafailablesuperclassinitializerwithanonfailablesubclassinitializer,theonlywaytodelegateuptothesuperclassinitializeristoforce-unwraptheresultofthefailablesuperclassinitializer.

Page 323: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Youcanoverrideafailableinitializerwithanonfailableinitializerbutnottheotherwayaround.

TheexamplebelowdefinesaclasscalledDocument.Thisclassmodelsadocumentthatcanbeinitializedwithanamepropertythatiseitheranonemptystringvalueornil,butcannotbeanemptystring:

1 classDocument{

2 varname:String?

3 //thisinitializercreatesadocumentwithanilname

value

4 init(){}

5 //thisinitializercreatesadocumentwithanonemptyname

value

6 init?(name:String){

7 ifname.isEmpty{returnnil}

8 self.name=name

9 }

10 }

ThenextexampledefinesasubclassofDocumentcalledAutomaticallyNamedDocument.TheAutomaticallyNamedDocumentsubclassoverridesbothofthedesignatedinitializersintroducedbyDocument.TheseoverridesensurethatanAutomaticallyNamedDocumentinstancehasaninitialnamevalueof"[Untitled]"iftheinstanceisinitializedwithoutaname,orifanemptystringispassedtotheinit(name:)initializer:

1 classAutomaticallyNamedDocument:Document{

2 overrideinit(){

3 super.init()

4 self.name="[Untitled]"

5 }

Page 324: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 overrideinit(name:String){

7 super.init()

8 ifname.isEmpty{

9 self.name="[Untitled]"

10 }else{

11 self.name=name

12 }

13 }

14 }

TheAutomaticallyNamedDocumentoverridesitssuperclass’sfailableinit?(name:)initializerwithanonfailableinit(name:)initializer.BecauseAutomaticallyNamedDocumentcopeswiththeemptystringcaseinadifferentwaythanitssuperclass,itsinitializerdoesnotneedtofail,andsoitprovidesanonfailableversionoftheinitializerinstead.

Youcanuseforcedunwrappinginaninitializertocallafailableinitializerfromthesuperclassaspartoftheimplementationofasubclass’snonfailableinitializer.Forexample,theUntitledDocumentsubclassbelowisalwaysnamed"[Untitled]",anditusesthefailableinit(name:)initializerfromitssuperclassduringinitialization.

1 classUntitledDocument:Document{

2 overrideinit(){

3 super.init(name:"[Untitled]")!

4 }

5 }

Inthiscase,iftheinit(name:)initializerofthesuperclasswereevercalledwithanemptystringasthename,theforcedunwrappingoperationwouldresultinaruntimeerror.However,becauseit’scalledwithastringconstant,youcanseethattheinitializerwon’tfail,sonoruntimeerrorcanoccurinthiscase.

Page 325: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theinit!FailableInitializerYoutypicallydefineafailableinitializerthatcreatesanoptionalinstanceoftheappropriatetypebyplacingaquestionmarkaftertheinitkeyword(init?).Alternatively,youcandefineafailableinitializerthatcreatesanimplicitlyunwrappedoptionalinstanceoftheappropriatetype.Dothisbyplacinganexclamationmarkaftertheinitkeyword(init!)insteadofaquestionmark.

Youcandelegatefrominit?toinit!andviceversa,andyoucanoverrideinit?withinit!andviceversa.Youcanalsodelegatefrominittoinit!,althoughdoingsowilltriggeranassertioniftheinit!initializercausesinitializationtofail.

RequiredInitializers

Writetherequiredmodifierbeforethedefinitionofaclassinitializertoindicatethateverysubclassoftheclassmustimplementthatinitializer:

1 classSomeClass{

2 requiredinit(){

3 //initializerimplementationgoeshere

4 }

5 }

Youmustalsowritetherequiredmodifierbeforeeverysubclassimplementationofarequiredinitializer,toindicatethattheinitializerrequirementappliestofurthersubclassesinthechain.Youdonotwritetheoverridemodifierwhenoverridingarequireddesignatedinitializer:

1 classSomeSubclass:SomeClass{

2 requiredinit(){

3 //subclassimplementationoftherequiredinitializer

goeshere

Page 326: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 }

5 }

NOTE

Youdonothavetoprovideanexplicitimplementationofarequiredinitializerifyoucansatisfytherequirementwithaninheritedinitializer.

SettingaDefaultPropertyValuewithaClosureorFunction

Ifastoredproperty’sdefaultvaluerequiressomecustomizationorsetup,youcanuseaclosureorglobalfunctiontoprovideacustomizeddefaultvalueforthatproperty.Wheneveranewinstanceofthetypethatthepropertybelongstoisinitialized,theclosureorfunctioniscalled,anditsreturnvalueisassignedastheproperty’sdefaultvalue.

Thesekindsofclosuresorfunctionstypicallycreateatemporaryvalueofthesametypeastheproperty,tailorthatvaluetorepresentthedesiredinitialstate,andthenreturnthattemporaryvaluetobeusedastheproperty’sdefaultvalue.

Here’saskeletonoutlineofhowaclosurecanbeusedtoprovideadefaultpropertyvalue:

1 classSomeClass{

2 letsomeProperty:SomeType={

3 //createadefaultvalueforsomePropertyinsidethis

closure

4 //someValuemustbeofthesametypeasSomeType

5 returnsomeValue

6 }()

7 }

Notethattheclosure’sendcurlybraceisfollowedbyanemptypairof

Page 327: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

parentheses.ThistellsSwifttoexecutetheclosureimmediately.Ifyouomittheseparentheses,youaretryingtoassigntheclosureitselftotheproperty,andnotthereturnvalueoftheclosure.

NOTE

Ifyouuseaclosuretoinitializeaproperty,rememberthattherestoftheinstancehasnotyetbeeninitializedatthepointthattheclosureisexecuted.Thismeansthatyoucannotaccessanyotherpropertyvaluesfromwithinyourclosure,evenifthosepropertieshavedefaultvalues.Youalsocannotusetheimplicitselfproperty,orcallanyoftheinstance’smethods.

TheexamplebelowdefinesastructurecalledChessboard,whichmodelsaboardforthegameofchess.Chessisplayedonan8x8board,withalternatingblackandwhitesquares.

Torepresentthisgameboard,theChessboardstructurehasasinglepropertycalledboardColors,whichisanarrayof64Boolvalues.Avalueoftrueinthearrayrepresentsablacksquareandavalueoffalserepresentsawhitesquare.Thefirstiteminthearrayrepresentsthetopleftsquareontheboardandthelastiteminthearrayrepresentsthebottomrightsquareontheboard.

TheboardColorsarrayisinitializedwithaclosuretosetupitscolorvalues:

1 structChessboard{

2 letboardColors:[Bool]={

3 vartemporaryBoard=[Bool]()

4 varisBlack=false

Page 328: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 foriin1...8{

6 forjin1...8{

7 temporaryBoard.append(isBlack)

8 isBlack=!isBlack

9 }

10 isBlack=!isBlack

11 }

12 returntemporaryBoard

13 }()

14 funcsquareIsBlackAt(row:Int,column:Int)->Bool{

15 returnboardColors[(row*8)+column]

16 }

17 }

WheneveranewChessboardinstanceiscreated,theclosureisexecuted,andthedefaultvalueofboardColorsiscalculatedandreturned.TheclosureintheexampleabovecalculatesandsetstheappropriatecolorforeachsquareontheboardinatemporaryarraycalledtemporaryBoard,andreturnsthistemporaryarrayastheclosure’sreturnvalueonceitssetupiscomplete.ThereturnedarrayvalueisstoredinboardColorsandcanbequeriedwiththesquareIsBlackAt(row:column:)utilityfunction:

1 letboard=Chessboard()

2 print(board.squareIsBlackAt(row:0,column:1))

3 //Prints"true"

4 print(board.squareIsBlackAt(row:7,column:7))

5 //Prints"false"

Page 329: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Deinitialization

Adeinitializeriscalledimmediatelybeforeaclassinstanceisdeallocated.Youwritedeinitializerswiththedeinitkeyword,similartohowinitializersarewrittenwiththeinitkeyword.Deinitializersareonlyavailableonclasstypes.

HowDeinitializationWorks

Swiftautomaticallydeallocatesyourinstanceswhentheyarenolongerneeded,tofreeupresources.Swifthandlesthememorymanagementofinstancesthroughautomaticreferencecounting(ARC),asdescribedinAutomaticReferenceCounting.Typicallyyoudon’tneedtoperformmanualcleanupwhenyourinstancesaredeallocated.However,whenyouareworkingwithyourownresources,youmightneedtoperformsomeadditionalcleanupyourself.Forexample,ifyoucreateacustomclasstoopenafileandwritesomedatatoit,youmightneedtoclosethefilebeforetheclassinstanceisdeallocated.

Classdefinitionscanhaveatmostonedeinitializerperclass.Thedeinitializerdoesnottakeanyparametersandiswrittenwithoutparentheses:

1 deinit{

2 //performthedeinitialization

3 }

Deinitializersarecalledautomatically,justbeforeinstancedeallocationtakesplace.Youarenotallowedtocalladeinitializeryourself.Superclassdeinitializersareinheritedbytheirsubclasses,andthesuperclassdeinitializeriscalledautomaticallyattheendofasubclassdeinitializerimplementation.Superclassdeinitializersarealwayscalled,evenifasubclassdoesnotprovideitsowndeinitializer.

Becauseaninstanceisnotdeallocateduntilafteritsdeinitializeriscalled,adeinitializercanaccessallpropertiesoftheinstanceitiscalledonandcan

Page 330: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

modifyitsbehaviorbasedonthoseproperties(suchaslookingupthenameofafilethatneedstobeclosed).

DeinitializersinAction

Here’sanexampleofadeinitializerinaction.Thisexampledefinestwonewtypes,BankandPlayer,forasimplegame.TheBankclassmanagesamade-upcurrency,whichcanneverhavemorethan10,000coinsincirculation.TherecanonlyeverbeoneBankinthegame,andsotheBankisimplementedasaclasswithtypepropertiesandmethodstostoreandmanageitscurrentstate:

1 classBank{

2 staticvarcoinsInBank=10_000

3 staticfuncdistribute(coinsnumberOfCoinsRequested:Int)-

>Int{

4 letnumberOfCoinsToVend=min(numberOfCoinsRequested,

coinsInBank)

5 coinsInBank-=numberOfCoinsToVend

6 returnnumberOfCoinsToVend

7 }

8 staticfuncreceive(coins:Int){

9 coinsInBank+=coins

10 }

11 }

BankkeepstrackofthecurrentnumberofcoinsitholdswithitscoinsInBankproperty.Italsoofferstwomethods—distribute(coins:)andreceive(coins:)—tohandlethedistributionandcollectionofcoins.

Thedistribute(coins:)methodchecksthatthereareenoughcoinsinthebankbeforedistributingthem.Iftherearenotenoughcoins,Bankreturnsasmallernumberthanthenumberthatwasrequested(andreturnszeroifnocoinsareleft

Page 331: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

inthebank).Itreturnsanintegervaluetoindicatetheactualnumberofcoinsthatwereprovided.

Thereceive(coins:)methodsimplyaddsthereceivednumberofcoinsbackintothebank’scoinstore.

ThePlayerclassdescribesaplayerinthegame.Eachplayerhasacertainnumberofcoinsstoredintheirpurseatanytime.Thisisrepresentedbytheplayer’scoinsInPurseproperty:

1 classPlayer{

2 varcoinsInPurse:Int

3 init(coins:Int){

4 coinsInPurse=Bank.distribute(coins:coins)

5 }

6 funcwin(coins:Int){

7 coinsInPurse+=Bank.distribute(coins:coins)

8 }

9 deinit{

10 Bank.receive(coins:coinsInPurse)

11 }

12 }

EachPlayerinstanceisinitializedwithastartingallowanceofaspecifiednumberofcoinsfromthebankduringinitialization,althoughaPlayerinstancemayreceivefewerthanthatnumberifnotenoughcoinsareavailable.

ThePlayerclassdefinesawin(coins:)method,whichretrievesacertainnumberofcoinsfromthebankandaddsthemtotheplayer’spurse.ThePlayerclassalsoimplementsadeinitializer,whichiscalledjustbeforeaPlayerinstanceisdeallocated.Here,thedeinitializersimplyreturnsalloftheplayer’scoinstothebank:

1 varplayerOne:Player?=Player(coins:100)

Page 332: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 print("Anewplayerhasjoinedthegamewith\

(playerOne!.coinsInPurse)coins")

3 //Prints"Anewplayerhasjoinedthegamewith100coins"

4 print("Therearenow\(Bank.coinsInBank)coinsleftinthe

bank")

5 //Prints"Therearenow9900coinsleftinthebank"

AnewPlayerinstanceiscreated,witharequestfor100coinsiftheyareavailable.ThisPlayerinstanceisstoredinanoptionalPlayervariablecalledplayerOne.Anoptionalvariableisusedhere,becauseplayerscanleavethegameatanypoint.Theoptionalletsyoutrackwhetherthereiscurrentlyaplayerinthegame.

BecauseplayerOneisanoptional,itisqualifiedwithanexclamationmark(!)whenitscoinsInPursepropertyisaccessedtoprintitsdefaultnumberofcoins,andwheneveritswin(coins:)methodiscalled:

1 playerOne!.win(coins:2_000)

2 print("PlayerOnewon2000coins&nowhas\

(playerOne!.coinsInPurse)coins")

3 //Prints"PlayerOnewon2000coins&nowhas2100coins"

4 print("Thebanknowonlyhas\(Bank.coinsInBank)coinsleft")

5 //Prints"Thebanknowonlyhas7900coinsleft"

Here,theplayerhaswon2,000coins.Theplayer’spursenowcontains2,100coins,andthebankhasonly7,900coinsleft.

1 playerOne=nil

2 print("PlayerOnehasleftthegame")

3 //Prints"PlayerOnehasleftthegame"

4 print("Thebanknowhas\(Bank.coinsInBank)coins")

5 //Prints"Thebanknowhas10000coins"

Page 333: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theplayerhasnowleftthegame.ThisisindicatedbysettingtheoptionalplayerOnevariabletonil,meaning“noPlayerinstance.”Atthepointthatthishappens,theplayerOnevariable’sreferencetothePlayerinstanceisbroken.NootherpropertiesorvariablesarestillreferringtothePlayerinstance,andsoitisdeallocatedinordertofreeupitsmemory.Justbeforethishappens,itsdeinitializeriscalledautomatically,anditscoinsarereturnedtothebank.

Page 334: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

OptionalChaining

Optionalchainingisaprocessforqueryingandcallingproperties,methods,andsubscriptsonanoptionalthatmightcurrentlybenil.Iftheoptionalcontainsavalue,theproperty,method,orsubscriptcallsucceeds;iftheoptionalisnil,theproperty,method,orsubscriptcallreturnsnil.Multiplequeriescanbechainedtogether,andtheentirechainfailsgracefullyifanylinkinthechainisnil.

NOTE

OptionalchaininginSwiftissimilartomessagingnilinObjective-C,butinawaythatworksforanytype,andthatcanbecheckedforsuccessorfailure.

OptionalChainingasanAlternativetoForcedUnwrapping

Youspecifyoptionalchainingbyplacingaquestionmark(?)aftertheoptionalvalueonwhichyouwishtocallaproperty,methodorsubscriptiftheoptionalisnon-nil.Thisisverysimilartoplacinganexclamationmark(!)afteranoptionalvaluetoforcetheunwrappingofitsvalue.Themaindifferenceisthatoptionalchainingfailsgracefullywhentheoptionalisnil,whereasforcedunwrappingtriggersaruntimeerrorwhentheoptionalisnil.

Toreflectthefactthatoptionalchainingcanbecalledonanilvalue,theresultofanoptionalchainingcallisalwaysanoptionalvalue,eveniftheproperty,method,orsubscriptyouarequeryingreturnsanon-optionalvalue.Youcanusethisoptionalreturnvaluetocheckwhethertheoptionalchainingcallwassuccessful(thereturnedoptionalcontainsavalue),ordidnotsucceedduetoanilvalueinthechain(thereturnedoptionalvalueisnil).

Specifically,theresultofanoptionalchainingcallisofthesametypeastheexpectedreturnvalue,butwrappedinanoptional.ApropertythatnormallyreturnsanIntwillreturnanInt?whenaccessedthroughoptionalchaining.

Thenextseveralcodesnippetsdemonstratehowoptionalchainingdiffersfrom

Page 335: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

forcedunwrappingandenablesyoutocheckforsuccess.

First,twoclassescalledPersonandResidencearedefined:

1 classPerson{

2 varresidence:Residence?

3 }

4

5 classResidence{

6 varnumberOfRooms=1

7 }

ResidenceinstanceshaveasingleIntpropertycallednumberOfRooms,withadefaultvalueof1.PersoninstanceshaveanoptionalresidencepropertyoftypeResidence?.

IfyoucreateanewPersoninstance,itsresidencepropertyisdefaultinitializedtonil,byvirtueofbeingoptional.Inthecodebelow,johnhasaresidencepropertyvalueofnil:

letjohn=Person()

IfyoutrytoaccessthenumberOfRoomspropertyofthisperson’sresidence,byplacinganexclamationmarkafterresidencetoforcetheunwrappingofitsvalue,youtriggeraruntimeerror,becausethereisnoresidencevaluetounwrap:

1 letroomCount=john.residence!.numberOfRooms

2 //thistriggersaruntimeerror

Thecodeabovesucceedswhenjohn.residencehasanon-nilvalueandwillsetroomCounttoanIntvaluecontainingtheappropriatenumberofrooms.However,thiscodealwaystriggersaruntimeerrorwhenresidenceisnil,asillustratedabove.

Page 336: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

OptionalchainingprovidesanalternativewaytoaccessthevalueofnumberOfRooms.Touseoptionalchaining,useaquestionmarkinplaceoftheexclamationmark:

1 ifletroomCount=john.residence?.numberOfRooms{

2 print("John'sresidencehas\(roomCount)room(s).")

3 }else{

4 print("Unabletoretrievethenumberofrooms.")

5 }

6 //Prints"Unabletoretrievethenumberofrooms."

ThistellsSwiftto“chain”ontheoptionalresidencepropertyandtoretrievethevalueofnumberOfRoomsifresidenceexists.

BecausetheattempttoaccessnumberOfRoomshasthepotentialtofail,theoptionalchainingattemptreturnsavalueoftypeInt?,or“optionalInt”.Whenresidenceisnil,asintheexampleabove,thisoptionalIntwillalsobenil,toreflectthefactthatitwasnotpossibletoaccessnumberOfRooms.TheoptionalIntisaccessedthroughoptionalbindingtounwraptheintegerandassignthenon-optionalvaluetotheroomCountvariable.

NotethatthisistrueeventhoughnumberOfRoomsisanon-optionalInt.ThefactthatitisqueriedthroughanoptionalchainmeansthatthecalltonumberOfRoomswillalwaysreturnanInt?insteadofanInt.

YoucanassignaResidenceinstancetojohn.residence,sothatitnolongerhasanilvalue:

john.residence=Residence()

john.residencenowcontainsanactualResidenceinstance,ratherthannil.IfyoutrytoaccessnumberOfRoomswiththesameoptionalchainingasbefore,itwillnowreturnanInt?thatcontainsthedefaultnumberOfRoomsvalueof1:

1 ifletroomCount=john.residence?.numberOfRooms{

Page 337: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 print("John'sresidencehas\(roomCount)room(s).")

3 }else{

4 print("Unabletoretrievethenumberofrooms.")

5 }

6 //Prints"John'sresidencehas1room(s)."

DefiningModelClassesforOptionalChaining

Youcanuseoptionalchainingwithcallstoproperties,methods,andsubscriptsthataremorethanoneleveldeep.Thisenablesyoutodrilldownintosubpropertieswithincomplexmodelsofinterrelatedtypes,andtocheckwhetheritispossibletoaccessproperties,methods,andsubscriptsonthosesubproperties.

Thecodesnippetsbelowdefinefourmodelclassesforuseinseveralsubsequentexamples,includingexamplesofmultileveloptionalchaining.TheseclassesexpanduponthePersonandResidencemodelfromabovebyaddingaRoomandAddressclass,withassociatedproperties,methods,andsubscripts.

ThePersonclassisdefinedinthesamewayasbefore:

1 classPerson{

2 varresidence:Residence?

3 }

TheResidenceclassismorecomplexthanbefore.Thistime,theResidenceclassdefinesavariablepropertycalledrooms,whichisinitializedwithanemptyarrayoftype[Room]:

1 classResidence{

2 varrooms=[Room]()

3 varnumberOfRooms:Int{

Page 338: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 returnrooms.count

5 }

6 subscript(i:Int)->Room{

7 get{

8 returnrooms[i]

9 }

10 set{

11 rooms[i]=newValue

12 }

13 }

14 funcprintNumberOfRooms(){

15 print("Thenumberofroomsis\(numberOfRooms)")

16 }

17 varaddress:Address?

18 }

BecausethisversionofResidencestoresanarrayofRoominstances,itsnumberOfRoomspropertyisimplementedasacomputedproperty,notastoredproperty.ThecomputednumberOfRoomspropertysimplyreturnsthevalueofthecountpropertyfromtheroomsarray.

Asashortcuttoaccessingitsroomsarray,thisversionofResidenceprovidesaread-writesubscriptthatprovidesaccesstotheroomattherequestedindexintheroomsarray.

ThisversionofResidencealsoprovidesamethodcalledprintNumberOfRooms,whichsimplyprintsthenumberofroomsintheresidence.

Finally,Residencedefinesanoptionalpropertycalledaddress,withatypeofAddress?.TheAddressclasstypeforthispropertyisdefinedbelow.

TheRoomclassusedfortheroomsarrayisasimpleclasswithonepropertycalledname,andaninitializertosetthatpropertytoasuitableroomname:

Page 339: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 classRoom{

2 letname:String

3 init(name:String){self.name=name}

4 }

ThefinalclassinthismodeliscalledAddress.ThisclasshasthreeoptionalpropertiesoftypeString?.Thefirsttwoproperties,buildingNameandbuildingNumber,arealternativewaystoidentifyaparticularbuildingaspartofanaddress.Thethirdproperty,street,isusedtonamethestreetforthataddress:

1 classAddress{

2 varbuildingName:String?

3 varbuildingNumber:String?

4 varstreet:String?

5 funcbuildingIdentifier()->String?{

6 ifletbuildingNumber=buildingNumber,letstreet=

street{

7 return"\(buildingNumber)\(street)"

8 }elseifbuildingName!=nil{

9 returnbuildingName

10 }else{

11 returnnil

12 }

13 }

14 }

TheAddressclassalsoprovidesamethodcalledbuildingIdentifier(),whichhasareturntypeofString?.ThismethodchecksthepropertiesoftheaddressandreturnsbuildingNameifithasavalue,orbuildingNumberconcatenatedwithstreetifbothhavevalues,ornilotherwise.

Page 340: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AccessingPropertiesThroughOptionalChaining

AsdemonstratedinOptionalChainingasanAlternativetoForcedUnwrapping,youcanuseoptionalchainingtoaccessapropertyonanoptionalvalue,andtocheckifthatpropertyaccessissuccessful.

UsetheclassesdefinedabovetocreateanewPersoninstance,andtrytoaccessitsnumberOfRoomspropertyasbefore:

1 letjohn=Person()

2 ifletroomCount=john.residence?.numberOfRooms{

3 print("John'sresidencehas\(roomCount)room(s).")

4 }else{

5 print("Unabletoretrievethenumberofrooms.")

6 }

7 //Prints"Unabletoretrievethenumberofrooms."

Becausejohn.residenceisnil,thisoptionalchainingcallfailsinthesamewayasbefore.

Youcanalsoattempttosetaproperty’svaluethroughoptionalchaining:

1 letsomeAddress=Address()

2 someAddress.buildingNumber="29"

3 someAddress.street="AcaciaRoad"

4 john.residence?.address=someAddress

Inthisexample,theattempttosettheaddresspropertyofjohn.residencewillfail,becausejohn.residenceiscurrentlynil.

Theassignmentispartoftheoptionalchaining,whichmeansnoneofthecodeontheright-handsideofthe=operatorisevaluated.Inthepreviousexample,it’snoteasytoseethatsomeAddressisneverevaluated,becauseaccessingaconstantdoesn’thaveanysideeffects.Thelistingbelowdoesthesameassignment,butitusesafunctiontocreatetheaddress.Thefunctionprints“Functionwascalled”

Page 341: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

beforereturningavalue,whichletsyouseewhethertheright-handsideofthe=operatorwasevaluated.

1 funccreateAddress()->Address{

2 print("Functionwascalled.")

3

4 letsomeAddress=Address()

5 someAddress.buildingNumber="29"

6 someAddress.street="AcaciaRoad"

7

8 returnsomeAddress

9 }

10 john.residence?.address=createAddress()

YoucantellthatthecreateAddress()functionisn’tcalled,becausenothingisprinted.

CallingMethodsThroughOptionalChaining

Youcanuseoptionalchainingtocallamethodonanoptionalvalue,andtocheckwhetherthatmethodcallissuccessful.Youcandothisevenifthatmethoddoesnotdefineareturnvalue.

TheprintNumberOfRooms()methodontheResidenceclassprintsthecurrentvalueofnumberOfRooms.Here’showthemethodlooks:

1 funcprintNumberOfRooms(){

2 print("Thenumberofroomsis\(numberOfRooms)")

3 }

Thismethoddoesnotspecifyareturntype.However,functionsandmethodswithnoreturntypehaveanimplicitreturntypeofVoid,asdescribedin

Page 342: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

FunctionsWithoutReturnValues.Thismeansthattheyreturnavalueof(),oranemptytuple.

Ifyoucallthismethodonanoptionalvaluewithoptionalchaining,themethod’sreturntypewillbeVoid?,notVoid,becausereturnvaluesarealwaysofanoptionaltypewhencalledthroughoptionalchaining.ThisenablesyoutouseanifstatementtocheckwhetheritwaspossibletocalltheprintNumberOfRooms()method,eventhoughthemethoddoesnotitselfdefineareturnvalue.ComparethereturnvaluefromtheprintNumberOfRoomscallagainstniltoseeifthemethodcallwassuccessful:

1 ifjohn.residence?.printNumberOfRooms()!=nil{

2 print("Itwaspossibletoprintthenumberofrooms.")

3 }else{

4 print("Itwasnotpossibletoprintthenumberofrooms.")

5 }

6 //Prints"Itwasnotpossibletoprintthenumberofrooms."

Thesameistrueifyouattempttosetapropertythroughoptionalchaining.TheexampleaboveinAccessingPropertiesThroughOptionalChainingattemptstosetanaddressvalueforjohn.residence,eventhoughtheresidencepropertyisnil.AnyattempttosetapropertythroughoptionalchainingreturnsavalueoftypeVoid?,whichenablesyoutocompareagainstniltoseeifthepropertywassetsuccessfully:

1 if(john.residence?.address=someAddress)!=nil{

2 print("Itwaspossibletosettheaddress.")

3 }else{

4 print("Itwasnotpossibletosettheaddress.")

5 }

6 //Prints"Itwasnotpossibletosettheaddress."

Page 343: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AccessingSubscriptsThroughOptionalChaining

Youcanuseoptionalchainingtotrytoretrieveandsetavaluefromasubscriptonanoptionalvalue,andtocheckwhetherthatsubscriptcallissuccessful.

NOTE

Whenyouaccessasubscriptonanoptionalvaluethroughoptionalchaining,youplacethequestionmarkbeforethesubscript’sbrackets,notafter.Theoptionalchainingquestionmarkalwaysfollowsimmediatelyafterthepartoftheexpressionthatisoptional.

Theexamplebelowtriestoretrievethenameofthefirstroomintheroomsarrayofthejohn.residencepropertyusingthesubscriptdefinedontheResidenceclass.Becausejohn.residenceiscurrentlynil,thesubscriptcallfails:

1 ifletfirstRoomName=john.residence?[0].name{

2 print("Thefirstroomnameis\(firstRoomName).")

3 }else{

4 print("Unabletoretrievethefirstroomname.")

5 }

6 //Prints"Unabletoretrievethefirstroomname."

Theoptionalchainingquestionmarkinthissubscriptcallisplacedimmediatelyafterjohn.residence,beforethesubscriptbrackets,becausejohn.residenceistheoptionalvalueonwhichoptionalchainingisbeingattempted.

Similarly,youcantrytosetanewvaluethroughasubscriptwithoptionalchaining:

john.residence?[0]=Room(name:"Bathroom")

Thissubscriptsettingattemptalsofails,becauseresidenceiscurrentlynil.

IfyoucreateandassignanactualResidenceinstancetojohn.residence,withoneormoreRoominstancesinitsroomsarray,youcanusetheResidencesubscripttoaccesstheactualitemsintheroomsarraythroughoptionalchaining:

Page 344: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letjohnsHouse=Residence()

2 johnsHouse.rooms.append(Room(name:"LivingRoom"))

3 johnsHouse.rooms.append(Room(name:"Kitchen"))

4 john.residence=johnsHouse

5

6 ifletfirstRoomName=john.residence?[0].name{

7 print("Thefirstroomnameis\(firstRoomName).")

8 }else{

9 print("Unabletoretrievethefirstroomname.")

10 }

11 //Prints"ThefirstroomnameisLivingRoom."

AccessingSubscriptsofOptionalTypeIfasubscriptreturnsavalueofoptionaltype—suchasthekeysubscriptofSwift’sDictionarytype—placeaquestionmarkafterthesubscript’sclosingbrackettochainonitsoptionalreturnvalue:

1 vartestScores=["Dave":[86,82,84],"Bev":[79,94,81]]

2 testScores["Dave"]?[0]=91

3 testScores["Bev"]?[0]+=1

4 testScores["Brian"]?[0]=72

5 //the"Dave"arrayisnow[91,82,84]andthe"Bev"arrayis

now[80,94,81]

TheexampleabovedefinesadictionarycalledtestScores,whichcontainstwokey-valuepairsthatmapaStringkeytoanarrayofIntvalues.Theexampleusesoptionalchainingtosetthefirstiteminthe"Dave"arrayto91;toincrementthefirstiteminthe"Bev"arrayby1;andtotrytosetthefirstiteminanarrayforakeyof"Brian".Thefirsttwocallssucceed,becausethetestScoresdictionarycontainskeysfor"Dave"and"Bev".Thethirdcallfails,becausethetestScoresdictionarydoesnotcontainakeyfor"Brian".

Page 345: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

LinkingMultipleLevelsofChaining

Youcanlinktogethermultiplelevelsofoptionalchainingtodrilldowntoproperties,methods,andsubscriptsdeeperwithinamodel.However,multiplelevelsofoptionalchainingdonotaddmorelevelsofoptionalitytothereturnedvalue.

Toputitanotherway:

Ifthetypeyouaretryingtoretrieveisnotoptional,itwillbecomeoptionalbecauseoftheoptionalchaining.

Ifthetypeyouaretryingtoretrieveisalreadyoptional,itwillnotbecomemoreoptionalbecauseofthechaining.

Therefore:

IfyoutrytoretrieveanIntvaluethroughoptionalchaining,anInt?isalwaysreturned,nomatterhowmanylevelsofchainingareused.

Similarly,ifyoutrytoretrieveanInt?valuethroughoptionalchaining,anInt?isalwaysreturned,nomatterhowmanylevelsofchainingareused.

Theexamplebelowtriestoaccessthestreetpropertyoftheaddresspropertyoftheresidencepropertyofjohn.Therearetwolevelsofoptionalchaininginusehere,tochainthroughtheresidenceandaddressproperties,bothofwhichareofoptionaltype:

1 ifletjohnsStreet=john.residence?.address?.street{

2 print("John'sstreetnameis\(johnsStreet).")

3 }else{

4 print("Unabletoretrievetheaddress.")

5 }

6 //Prints"Unabletoretrievetheaddress."

Thevalueofjohn.residencecurrentlycontainsavalidResidenceinstance.However,thevalueofjohn.residence.addressiscurrentlynil.Becauseofthis,

Page 346: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thecalltojohn.residence?.address?.streetfails.

Notethatintheexampleabove,youaretryingtoretrievethevalueofthestreetproperty.ThetypeofthispropertyisString?.Thereturnvalueofjohn.residence?.address?.streetisthereforealsoString?,eventhoughtwolevelsofoptionalchainingareappliedinadditiontotheunderlyingoptionaltypeoftheproperty.

IfyousetanactualAddressinstanceasthevalueforjohn.residence.address,andsetanactualvaluefortheaddress’sstreetproperty,youcanaccessthevalueofthestreetpropertythroughmultileveloptionalchaining:

1 letjohnsAddress=Address()

2 johnsAddress.buildingName="TheLarches"

3 johnsAddress.street="LaurelStreet"

4 john.residence?.address=johnsAddress

5

6 ifletjohnsStreet=john.residence?.address?.street{

7 print("John'sstreetnameis\(johnsStreet).")

8 }else{

9 print("Unabletoretrievetheaddress.")

10 }

11 //Prints"John'sstreetnameisLaurelStreet."

Inthisexample,theattempttosettheaddresspropertyofjohn.residencewillsucceed,becausethevalueofjohn.residencecurrentlycontainsavalidResidenceinstance.

ChainingonMethodswithOptionalReturnValues

Thepreviousexampleshowshowtoretrievethevalueofapropertyofoptionaltypethroughoptionalchaining.Youcanalsouseoptionalchainingtocalla

Page 347: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

methodthatreturnsavalueofoptionaltype,andtochainonthatmethod’sreturnvalueifneeded.

TheexamplebelowcallstheAddressclass’sbuildingIdentifier()methodthroughoptionalchaining.ThismethodreturnsavalueoftypeString?.Asdescribedabove,theultimatereturntypeofthismethodcallafteroptionalchainingisalsoString?:

1 ifletbuildingIdentifier=

john.residence?.address?.buildingIdentifier(){

2 print("John'sbuildingidentifieris\

(buildingIdentifier).")

3 }

4 //Prints"John'sbuildingidentifierisTheLarches."

Ifyouwanttoperformfurtheroptionalchainingonthismethod’sreturnvalue,placetheoptionalchainingquestionmarkafterthemethod’sparentheses:

1 ifletbeginsWithThe=

2

john.residence?.address?.buildingIdentifier()?.hasPrefix("The"

{

3 ifbeginsWithThe{

4 print("John'sbuildingidentifierbeginswith

\"The\".")

5 }else{

6 print("John'sbuildingidentifierdoesnotbeginwith

\"The\".")

7 }

8 }

9 //Prints"John'sbuildingidentifierbeginswith"The"."

Page 348: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Intheexampleabove,youplacetheoptionalchainingquestionmarkaftertheparentheses,becausetheoptionalvalueyouarechainingonisthebuildingIdentifier()method’sreturnvalue,andnotthebuildingIdentifier()methoditself.

Page 349: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ErrorHandling

Errorhandlingistheprocessofrespondingtoandrecoveringfromerrorconditionsinyourprogram.Swiftprovidesfirst-classsupportforthrowing,catching,propagating,andmanipulatingrecoverableerrorsatruntime.

Someoperationsaren’tguaranteedtoalwayscompleteexecutionorproduceausefuloutput.Optionalsareusedtorepresenttheabsenceofavalue,butwhenanoperationfails,it’softenusefultounderstandwhatcausedthefailure,sothatyourcodecanrespondaccordingly.

Asanexample,considerthetaskofreadingandprocessingdatafromafileondisk.Thereareanumberofwaysthistaskcanfail,includingthefilenotexistingatthespecifiedpath,thefilenothavingreadpermissions,orthefilenotbeingencodedinacompatibleformat.Distinguishingamongthesedifferentsituationsallowsaprogramtoresolvesomeerrorsandtocommunicatetotheuseranyerrorsitcan’tresolve.

NOTE

ErrorhandlinginSwiftinteroperateswitherrorhandlingpatternsthatusetheNSErrorclassinCocoaandObjective-C.Formoreinformationaboutthisclass,seeHandlingCocoaErrorsinSwift.

RepresentingandThrowingErrors

InSwift,errorsarerepresentedbyvaluesoftypesthatconformtotheErrorprotocol.Thisemptyprotocolindicatesthatatypecanbeusedforerrorhandling.

Swiftenumerationsareparticularlywellsuitedtomodelingagroupofrelatederrorconditions,withassociatedvaluesallowingforadditionalinformationaboutthenatureofanerrortobecommunicated.Forexample,here’showyoumightrepresenttheerrorconditionsofoperatingavendingmachineinsideagame:

Page 350: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 enumVendingMachineError:Error{

2 caseinvalidSelection

3 caseinsufficientFunds(coinsNeeded:Int)

4 caseoutOfStock

5 }

Throwinganerrorletsyouindicatethatsomethingunexpectedhappenedandthenormalflowofexecutioncan’tcontinue.Youuseathrowstatementtothrowanerror.Forexample,thefollowingcodethrowsanerrortoindicatethatfiveadditionalcoinsareneededbythevendingmachine:

throwVendingMachineError.insufficientFunds(coinsNeeded:5)

HandlingErrors

Whenanerroristhrown,somesurroundingpieceofcodemustberesponsibleforhandlingtheerror—forexample,bycorrectingtheproblem,tryinganalternativeapproach,orinformingtheuserofthefailure.

TherearefourwaystohandleerrorsinSwift.Youcanpropagatetheerrorfromafunctiontothecodethatcallsthatfunction,handletheerrorusingado-catchstatement,handletheerrorasanoptionalvalue,orassertthattheerrorwillnotoccur.Eachapproachisdescribedinasectionbelow.

Whenafunctionthrowsanerror,itchangestheflowofyourprogram,soit’simportantthatyoucanquicklyidentifyplacesinyourcodethatcanthrowerrors.Toidentifytheseplacesinyourcode,writethetrykeyword—orthetry?ortry!variation—beforeapieceofcodethatcallsafunction,method,orinitializerthatcanthrowanerror.Thesekeywordsaredescribedinthesectionsbelow.

NOTE

ErrorhandlinginSwiftresemblesexceptionhandlinginotherlanguages,withtheuseofthetry,catchandthrowkeywords.Unlikeexceptionhandlinginmanylanguages—includingObjective-C—errorhandlinginSwiftdoesnotinvolveunwindingthecallstack,aprocessthatcanbe

Page 351: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

computationallyexpensive.Assuch,theperformancecharacteristicsofathrowstatementarecomparabletothoseofareturnstatement.

PropagatingErrorsUsingThrowingFunctionsToindicatethatafunction,method,orinitializercanthrowanerror,youwritethethrowskeywordinthefunction’sdeclarationafteritsparameters.Afunctionmarkedwiththrowsiscalledathrowingfunction.Ifthefunctionspecifiesareturntype,youwritethethrowskeywordbeforethereturnarrow(->).

1 funccanThrowErrors()throws->String

2

3 funccannotThrowErrors()->String

Athrowingfunctionpropagateserrorsthatarethrowninsideofittothescopefromwhichit’scalled.

NOTE

Onlythrowingfunctionscanpropagateerrors.Anyerrorsthrowninsideanonthrowingfunctionmustbehandledinsidethefunction.

Intheexamplebelow,theVendingMachineclasshasavend(itemNamed:)methodthatthrowsanappropriateVendingMachineErroriftherequesteditemisnotavailable,isoutofstock,orhasacostthatexceedsthecurrentdepositedamount:

1 structItem{

2 varprice:Int

3 varcount:Int

4 }

5

6 classVendingMachine{

7 varinventory=[

Page 352: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 "CandyBar":Item(price:12,count:7),

9 "Chips":Item(price:10,count:4),

10 "Pretzels":Item(price:7,count:11)

11 ]

12 varcoinsDeposited=0

13

14 funcvend(itemNamedname:String)throws{

15 guardletitem=inventory[name]else{

16 throwVendingMachineError.invalidSelection

17 }

18

19 guarditem.count>0else{

20 throwVendingMachineError.outOfStock

21 }

22

23 guarditem.price<=coinsDepositedelse{

24 throw

VendingMachineError.insufficientFunds(coinsNeeded:

item.price-coinsDeposited)

25 }

26

27 coinsDeposited-=item.price

28

29 varnewItem=item

30 newItem.count-=1

31 inventory[name]=newItem

32

33 print("Dispensing\(name)")

34 }

35 }

Page 353: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theimplementationofthevend(itemNamed:)methodusesguardstatementstoexitthemethodearlyandthrowappropriateerrorsifanyoftherequirementsforpurchasingasnackaren’tmet.Becauseathrowstatementimmediatelytransfersprogramcontrol,anitemwillbevendedonlyifalloftheserequirementsaremet.

Becausethevend(itemNamed:)methodpropagatesanyerrorsitthrows,anycodethatcallsthismethodmusteitherhandletheerrors—usingado-catchstatement,try?,ortry!—orcontinuetopropagatethem.Forexample,thebuyFavoriteSnack(person:vendingMachine:)intheexamplebelowisalsoathrowingfunction,andanyerrorsthatthevend(itemNamed:)methodthrowswillpropagateuptothepointwherethebuyFavoriteSnack(person:vendingMachine:)functioniscalled.

1 letfavoriteSnacks=[

2 "Alice":"Chips",

3 "Bob":"Licorice",

4 "Eve":"Pretzels",

5 ]

6 funcbuyFavoriteSnack(person:String,vendingMachine:

VendingMachine)throws{

7 letsnackName=favoriteSnacks[person]??"CandyBar"

8 tryvendingMachine.vend(itemNamed:snackName)

9 }

Inthisexample,thebuyFavoriteSnack(person:vendingMachine:)functionlooksupagivenperson’sfavoritesnackandtriestobuyitforthembycallingthevend(itemNamed:)method.Becausethevend(itemNamed:)methodcanthrowanerror,it’scalledwiththetrykeywordinfrontofit.

Throwinginitializerscanpropagateerrorsinthesamewayasthrowingfunctions.Forexample,theinitializerforthePurchasedSnackstructureinthelistingbelowcallsathrowingfunctionaspartoftheinitializationprocess,andithandlesanyerrorsthatitencountersbypropagatingthemtoitscaller.

Page 354: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 structPurchasedSnack{

2 letname:String

3 init(name:String,vendingMachine:VendingMachine)throws{

4 tryvendingMachine.vend(itemNamed:name)

5 self.name=name

6 }

7 }

HandlingErrorsUsingDo-CatchYouuseado-catchstatementtohandleerrorsbyrunningablockofcode.Ifanerroristhrownbythecodeinthedoclause,itismatchedagainstthecatchclausestodeterminewhichoneofthemcanhandletheerror.

Hereisthegeneralformofado-catchstatement:

do{

try expression

statements

}catch pattern1 {

statements

}catch pattern2 where condition {

statements

}catch{

statements

}

Youwriteapatternaftercatchtoindicatewhaterrorsthatclausecanhandle.Ifacatchclausedoesn’thaveapattern,theclausematchesanyerrorandbindstheerrortoalocalconstantnamederror.Formoreinformationaboutpatternmatching,seePatterns.

Forexample,thefollowingcodematchesagainstallthreecasesofthe

Page 355: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

VendingMachineErrorenumeration.

1 varvendingMachine=VendingMachine()

2 vendingMachine.coinsDeposited=8

3 do{

4 trybuyFavoriteSnack(person:"Alice",vendingMachine:

vendingMachine)

5 print("Success!Yum.")

6 }catchVendingMachineError.invalidSelection{

7 print("InvalidSelection.")

8 }catchVendingMachineError.outOfStock{

9 print("OutofStock.")

10 }catchVendingMachineError.insufficientFunds(letcoinsNeeded)

{

11 print("Insufficientfunds.Pleaseinsertanadditional\

(coinsNeeded)coins.")

12 }catch{

13 print("Unexpectederror:\(error).")

14 }

15 //Prints"Insufficientfunds.Pleaseinsertanadditional2

coins."

Intheaboveexample,thebuyFavoriteSnack(person:vendingMachine:)functioniscalledinatryexpression,becauseitcanthrowanerror.Ifanerroristhrown,executionimmediatelytransferstothecatchclauses,whichdecidewhethertoallowpropagationtocontinue.Ifnopatternismatched,theerrorgetscaughtbythefinalcatchclauseandisboundtoalocalerrorconstant.Ifnoerroristhrown,theremainingstatementsinthedostatementareexecuted.

Thecatchclausesdon’thavetohandleeverypossibleerrorthatthecodeinthedoclausecanthrow.Ifnoneofthecatchclauseshandletheerror,theerrorpropagatestothesurroundingscope.However,thepropagatederrormustbe

Page 356: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

handledbysomesurroundingscope.Inanonthrowingfunction,anenclosingdo-catchclausemusthandletheerror.Inathrowingfunction,eitheranenclosingdo-catchclauseorthecallermusthandletheerror.Iftheerrorpropagatestothetop-levelscopewithoutbeinghandled,you’llgetaruntimeerror.

Forexample,theaboveexamplecanbewrittensoanyerrorthatisn’taVendingMachineErrorisinsteadcaughtbythecallingfunction:

1 funcnourish(withitem:String)throws{

2 do{

3 tryvendingMachine.vend(itemNamed:item)

4 }catchisVendingMachineError{

5 print("Invalidselection,outofstock,ornotenough

money.")

6 }

7 }

8

9 do{

10 trynourish(with:"Beet-FlavoredChips")

11 }catch{

12 print("Unexpectednon-vending-machine-relatederror:\

(error)")

13 }

14 //Prints"Invalidselection,outofstock,ornotenough

money."

Inthenourish(with:)function,ifvend(itemNamed:)throwsanerrorthat’soneofthecasesoftheVendingMachineErrorenumeration,nourish(with:)handlestheerrorbyprintingamessage.Otherwise,nourish(with:)propagatestheerrortoitscallsite.Theerroristhencaughtbythegeneralcatchclause.

Page 357: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ConvertingErrorstoOptionalValuesYouusetry?tohandleanerrorbyconvertingittoanoptionalvalue.Ifanerroristhrownwhileevaluatingthetry?expression,thevalueoftheexpressionisnil.Forexample,inthefollowingcodexandyhavethesamevalueandbehavior:

1 funcsomeThrowingFunction()throws->Int{

2 //...

3 }

4

5 letx=try?someThrowingFunction()

6

7 lety:Int?

8 do{

9 y=trysomeThrowingFunction()

10 }catch{

11 y=nil

12 }

IfsomeThrowingFunction()throwsanerror,thevalueofxandyisnil.Otherwise,thevalueofxandyisthevaluethatthefunctionreturned.NotethatxandyareanoptionalofwhatevertypesomeThrowingFunction()returns.Herethefunctionreturnsaninteger,soxandyareoptionalintegers.

Usingtry?letsyouwriteconciseerrorhandlingcodewhenyouwanttohandleallerrorsinthesameway.Forexample,thefollowingcodeusesseveralapproachestofetchdata,orreturnsnilifalloftheapproachesfail.

1 funcfetchData()->Data?{

2 ifletdata=try?fetchDataFromDisk(){returndata}

3 ifletdata=try?fetchDataFromServer(){returndata}

4 returnnil

5 }

Page 358: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

DisablingErrorPropagationSometimesyouknowathrowingfunctionormethodwon’t,infact,throwanerroratruntime.Onthoseoccasions,youcanwritetry!beforetheexpressiontodisableerrorpropagationandwrapthecallinaruntimeassertionthatnoerrorwillbethrown.Ifanerroractuallyisthrown,you’llgetaruntimeerror.

Forexample,thefollowingcodeusesaloadImage(atPath:)function,whichloadstheimageresourceatagivenpathorthrowsanerroriftheimagecan’tbeloaded.Inthiscase,becausetheimageisshippedwiththeapplication,noerrorwillbethrownatruntime,soitisappropriatetodisableerrorpropagation.

letphoto=try!loadImage(atPath:"./Resources/John

Appleseed.jpg")

SpecifyingCleanupActions

Youuseadeferstatementtoexecuteasetofstatementsjustbeforecodeexecutionleavesthecurrentblockofcode.Thisstatementletsyoudoanynecessarycleanupthatshouldbeperformedregardlessofhowexecutionleavesthecurrentblockofcode—whetheritleavesbecauseanerrorwasthrownorbecauseofastatementsuchasreturnorbreak.Forexample,youcanuseadeferstatementtoensurethatfiledescriptorsareclosedandmanuallyallocatedmemoryisfreed.

Adeferstatementdefersexecutionuntilthecurrentscopeisexited.Thisstatementconsistsofthedeferkeywordandthestatementstobeexecutedlater.Thedeferredstatementsmaynotcontainanycodethatwouldtransfercontroloutofthestatements,suchasabreakorareturnstatement,orbythrowinganerror.Deferredactionsareexecutedinthereverseoftheorderthatthey’rewritteninyoursourcecode.Thatis,thecodeinthefirstdeferstatementexecuteslast,thecodeintheseconddeferstatementexecutessecondtolast,andsoon.Thelastdeferstatementinsourcecodeorderexecutesfirst.

1 funcprocessFile(filename:String)throws{

Page 359: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 ifexists(filename){

3 letfile=open(filename)

4 defer{

5 close(file)

6 }

7 whileletline=tryfile.readline(){

8 //Workwiththefile.

9 }

10 //close(file)iscalledhere,attheendofthe

scope.

11 }

12 }

Theaboveexampleusesadeferstatementtoensurethattheopen(_:)functionhasacorrespondingcalltoclose(_:).

NOTE

Youcanuseadeferstatementevenwhennoerrorhandlingcodeisinvolved.

Page 360: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TypeCasting

Typecastingisawaytocheckthetypeofaninstance,ortotreatthatinstanceasadifferentsuperclassorsubclassfromsomewhereelseinitsownclasshierarchy.

TypecastinginSwiftisimplementedwiththeisandasoperators.Thesetwooperatorsprovideasimpleandexpressivewaytocheckthetypeofavalueorcastavaluetoadifferenttype.

Youcanalsousetypecastingtocheckwhetheratypeconformstoaprotocol,asdescribedinCheckingforProtocolConformance.

DefiningaClassHierarchyforTypeCasting

Youcanusetypecastingwithahierarchyofclassesandsubclassestocheckthetypeofaparticularclassinstanceandtocastthatinstancetoanotherclasswithinthesamehierarchy.Thethreecodesnippetsbelowdefineahierarchyofclassesandanarraycontaininginstancesofthoseclasses,foruseinanexampleoftypecasting.

ThefirstsnippetdefinesanewbaseclasscalledMediaItem.Thisclassprovidesbasicfunctionalityforanykindofitemthatappearsinadigitalmedialibrary.Specifically,itdeclaresanamepropertyoftypeString,andaninitnameinitializer.(Itisassumedthatallmediaitems,includingallmoviesandsongs,willhaveaname.)

1 classMediaItem{

2 varname:String

3 init(name:String){

4 self.name=name

5 }

Page 361: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 }

ThenextsnippetdefinestwosubclassesofMediaItem.Thefirstsubclass,Movie,encapsulatesadditionalinformationaboutamovieorfilm.ItaddsadirectorpropertyontopofthebaseMediaItemclass,withacorrespondinginitializer.Thesecondsubclass,Song,addsanartistpropertyandinitializerontopofthebaseclass:

1 classMovie:MediaItem{

2 vardirector:String

3 init(name:String,director:String){

4 self.director=director

5 super.init(name:name)

6 }

7 }

8

9 classSong:MediaItem{

10 varartist:String

11 init(name:String,artist:String){

12 self.artist=artist

13 super.init(name:name)

14 }

15 }

Thefinalsnippetcreatesaconstantarraycalledlibrary,whichcontainstwoMovieinstancesandthreeSonginstances.Thetypeofthelibraryarrayisinferredbyinitializingitwiththecontentsofanarrayliteral.Swift’stypecheckerisabletodeducethatMovieandSonghaveacommonsuperclassofMediaItem,andsoitinfersatypeof[MediaItem]forthelibraryarray:

1 letlibrary=[

2 Movie(name:"Casablanca",director:"MichaelCurtiz"),

Page 362: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 Song(name:"BlueSuedeShoes",artist:"ElvisPresley"),

4 Movie(name:"CitizenKane",director:"OrsonWelles"),

5 Song(name:"TheOneAndOnly",artist:"ChesneyHawkes"),

6 Song(name:"NeverGonnaGiveYouUp",artist:"Rick

Astley")

7 ]

8 //thetypeof"library"isinferredtobe[MediaItem]

TheitemsstoredinlibraryarestillMovieandSonginstancesbehindthescenes.However,ifyouiterateoverthecontentsofthisarray,theitemsyoureceivebackaretypedasMediaItem,andnotasMovieorSong.Inordertoworkwiththemastheirnativetype,youneedtochecktheirtype,ordowncastthemtoadifferenttype,asdescribedbelow.

CheckingType

Usethetypecheckoperator(is)tocheckwhetheraninstanceisofacertainsubclasstype.Thetypecheckoperatorreturnstrueiftheinstanceisofthatsubclasstypeandfalseifitisnot.

Theexamplebelowdefinestwovariables,movieCountandsongCount,whichcountthenumberofMovieandSonginstancesinthelibraryarray:

1 varmovieCount=0

2 varsongCount=0

3

4 foriteminlibrary{

5 ifitemisMovie{

6 movieCount+=1

7 }elseifitemisSong{

8 songCount+=1

Page 363: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 }

10 }

11

12 print("Medialibrarycontains\(movieCount)moviesand\

(songCount)songs")

13 //Prints"Medialibrarycontains2moviesand3songs"

Thisexampleiteratesthroughallitemsinthelibraryarray.Oneachpass,thefor-inloopsetstheitemconstanttothenextMediaIteminthearray.

itemisMoviereturnstrueifthecurrentMediaItemisaMovieinstanceandfalseifitisnot.Similarly,itemisSongcheckswhethertheitemisaSonginstance.Attheendofthefor-inloop,thevaluesofmovieCountandsongCountcontainacountofhowmanyMediaIteminstanceswerefoundofeachtype.

Downcasting

Aconstantorvariableofacertainclasstypemayactuallyrefertoaninstanceofasubclassbehindthescenes.Whereyoubelievethisisthecase,youcantrytodowncasttothesubclasstypewithatypecastoperator(as?oras!).

Becausedowncastingcanfail,thetypecastoperatorcomesintwodifferentforms.Theconditionalform,as?,returnsanoptionalvalueofthetypeyouaretryingtodowncastto.Theforcedform,as!,attemptsthedowncastandforce-unwrapstheresultasasinglecompoundaction.

Usetheconditionalformofthetypecastoperator(as?)whenyouarenotsureifthedowncastwillsucceed.Thisformoftheoperatorwillalwaysreturnanoptionalvalue,andthevaluewillbenilifthedowncastwasnotpossible.Thisenablesyoutocheckforasuccessfuldowncast.

Usetheforcedformofthetypecastoperator(as!)onlywhenyouaresurethatthedowncastwillalwayssucceed.Thisformoftheoperatorwilltriggeraruntimeerrorifyoutrytodowncasttoanincorrectclasstype.

Page 364: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheexamplebelowiteratesovereachMediaIteminlibrary,andprintsanappropriatedescriptionforeachitem.Todothis,itneedstoaccesseachitemasatrueMovieorSong,andnotjustasaMediaItem.ThisisnecessaryinorderforittobeabletoaccessthedirectororartistpropertyofaMovieorSongforuseinthedescription.

Inthisexample,eachiteminthearraymightbeaMovie,oritmightbeaSong.Youdon’tknowinadvancewhichactualclasstouseforeachitem,andsoitisappropriatetousetheconditionalformofthetypecastoperator(as?)tocheckthedowncasteachtimethroughtheloop:

1 foriteminlibrary{

2 ifletmovie=itemas?Movie{

3 print("Movie:\(movie.name),dir.\(movie.director)")

4 }elseifletsong=itemas?Song{

5 print("Song:\(song.name),by\(song.artist)")

6 }

7 }

8

9 //Movie:Casablanca,dir.MichaelCurtiz

10 //Song:BlueSuedeShoes,byElvisPresley

11 //Movie:CitizenKane,dir.OrsonWelles

12 //Song:TheOneAndOnly,byChesneyHawkes

13 //Song:NeverGonnaGiveYouUp,byRickAstley

TheexamplestartsbytryingtodowncastthecurrentitemasaMovie.BecauseitemisaMediaIteminstance,it’spossiblethatitmightbeaMovie;equally,it’salsopossiblethatitmightbeaSong,orevenjustabaseMediaItem.Becauseofthisuncertainty,theas?formofthetypecastoperatorreturnsanoptionalvaluewhenattemptingtodowncasttoasubclasstype.Theresultofitemas?MovieisoftypeMovie?,or“optionalMovie”.

DowncastingtoMoviefailswhenappliedtotheSonginstancesinthelibraryarray.Tocopewiththis,theexampleaboveusesoptionalbindingtocheck

Page 365: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

whethertheoptionalMovieactuallycontainsavalue(thatis,tofindoutwhetherthedowncastsucceeded.)Thisoptionalbindingiswritten“ifletmovie=itemas?Movie”,whichcanbereadas:

“TrytoaccessitemasaMovie.Ifthisissuccessful,setanewtemporaryconstantcalledmovietothevaluestoredinthereturnedoptionalMovie.”

Ifthedowncastingsucceeds,thepropertiesofmoviearethenusedtoprintadescriptionforthatMovieinstance,includingthenameofitsdirector.AsimilarprincipleisusedtocheckforSonginstances,andtoprintanappropriatedescription(includingartistname)wheneveraSongisfoundinthelibrary.

NOTE

Castingdoesnotactuallymodifytheinstanceorchangeitsvalues.Theunderlyinginstanceremainsthesame;itissimplytreatedandaccessedasaninstanceofthetypetowhichithasbeencast.

TypeCastingforAnyandAnyObject

Swiftprovidestwospecialtypesforworkingwithnonspecifictypes:

Anycanrepresentaninstanceofanytypeatall,includingfunctiontypes.

AnyObjectcanrepresentaninstanceofanyclasstype.

UseAnyandAnyObjectonlywhenyouexplicitlyneedthebehaviorandcapabilitiestheyprovide.Itisalwaysbettertobespecificaboutthetypesyouexpecttoworkwithinyourcode.

Here’sanexampleofusingAnytoworkwithamixofdifferenttypes,includingfunctiontypesandnonclasstypes.Theexamplecreatesanarraycalledthings,whichcanstorevaluesoftypeAny:

1 varthings=[Any]()

2

3 things.append(0)

Page 366: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 things.append(0.0)

5 things.append(42)

6 things.append(3.14159)

7 things.append("hello")

8 things.append((3.0,5.0))

9 things.append(Movie(name:"Ghostbusters",director:"Ivan

Reitman"))

10 things.append({(name:String)->Stringin"Hello,\(name)"

})

ThethingsarraycontainstwoIntvalues,twoDoublevalues,aStringvalue,atupleoftype(Double,Double),themovie“Ghostbusters”,andaclosureexpressionthattakesaStringvalueandreturnsanotherStringvalue.

TodiscoverthespecifictypeofaconstantorvariablethatisknownonlytobeoftypeAnyorAnyObject,youcanuseanisoraspatterninaswitchstatement’scases.Theexamplebelowiteratesovertheitemsinthethingsarrayandqueriesthetypeofeachitemwithaswitchstatement.Severaloftheswitchstatement’scasesbindtheirmatchedvaluetoaconstantofthespecifiedtypetoenableitsvaluetobeprinted:

1 forthinginthings{

2 switchthing{

3 case0asInt:

4 print("zeroasanInt")

5 case0asDouble:

6 print("zeroasaDouble")

7 caseletsomeIntasInt:

8 print("anintegervalueof\(someInt)")

9 caseletsomeDoubleasDoublewheresomeDouble>0:

10 print("apositivedoublevalueof\(someDouble)")

11 caseisDouble:

Page 367: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

12 print("someotherdoublevaluethatIdon'twantto

print")

13 caseletsomeStringasString:

14 print("astringvalueof\"\(someString)\"")

15 caselet(x,y)as(Double,Double):

16 print("an(x,y)pointat\(x),\(y)")

17 caseletmovieasMovie:

18 print("amoviecalled\(movie.name),dir.\

(movie.director)")

19 caseletstringConverteras(String)->String:

20 print(stringConverter("Michael"))

21 default:

22 print("somethingelse")

23 }

24 }

25

26 //zeroasanInt

27 //zeroasaDouble

28 //anintegervalueof42

29 //apositivedoublevalueof3.14159

30 //astringvalueof"hello"

31 //an(x,y)pointat3.0,5.0

32 //amoviecalledGhostbusters,dir.IvanReitman

33 //Hello,Michael

NOTE

TheAnytyperepresentsvaluesofanytype,includingoptionaltypes.SwiftgivesyouawarningifyouuseanoptionalvaluewhereavalueoftypeAnyisexpected.IfyoureallydoneedtouseanoptionalvalueasanAnyvalue,youcanusetheasoperatortoexplicitlycasttheoptionaltoAny,asshownbelow.

Page 368: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letoptionalNumber:Int?=3

2 things.append(optionalNumber)//Warning

3 things.append(optionalNumberasAny)//Nowarning

Page 369: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NestedTypes

Enumerationsareoftencreatedtosupportaspecificclassorstructure’sfunctionality.Similarly,itcanbeconvenienttodefineutilityclassesandstructurespurelyforusewithinthecontextofamorecomplextype.Toaccomplishthis,Swiftenablesyoutodefinenestedtypes,wherebyyounestsupportingenumerations,classes,andstructureswithinthedefinitionofthetypetheysupport.

Tonestatypewithinanothertype,writeitsdefinitionwithintheouterbracesofthetypeitsupports.Typescanbenestedtoasmanylevelsasarerequired.

NestedTypesinAction

TheexamplebelowdefinesastructurecalledBlackjackCard,whichmodelsaplayingcardasusedinthegameofBlackjack.TheBlackjackCardstructurecontainstwonestedenumerationtypescalledSuitandRank.

InBlackjack,theAcecardshaveavalueofeitheroneoreleven.ThisfeatureisrepresentedbyastructurecalledValues,whichisnestedwithintheRankenumeration:

1 structBlackjackCard{

2

3 //nestedSuitenumeration

4 enumSuit:Character{

5 casespades="♠",hearts="♡",diamonds="♢",clubs

="♣"

6 }

7

8 //nestedRankenumeration

Page 370: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 enumRank:Int{

10 casetwo=2,three,four,five,six,seven,eight,

nine,ten

11 casejack,queen,king,ace

12 structValues{

13 letfirst:Int,second:Int?

14 }

15 varvalues:Values{

16 switchself{

17 case.ace:

18 returnValues(first:1,second:11)

19 case.jack,.queen,.king:

20 returnValues(first:10,second:nil)

21 default:

22 returnValues(first:self.rawValue,second:

nil)

23 }

24 }

25 }

26

27 //BlackjackCardpropertiesandmethods

28 letrank:Rank,suit:Suit

29 vardescription:String{

30 varoutput="suitis\(suit.rawValue),"

31 output+="valueis\(rank.values.first)"

32 ifletsecond=rank.values.second{

33 output+="or\(second)"

34 }

35 returnoutput

36 }

Page 371: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

37 }

TheSuitenumerationdescribesthefourcommonplayingcardsuits,togetherwitharawCharactervaluetorepresenttheirsymbol.

TheRankenumerationdescribesthethirteenpossibleplayingcardranks,togetherwitharawIntvaluetorepresenttheirfacevalue.(ThisrawIntvalueisnotusedfortheJack,Queen,King,andAcecards.)

Asmentionedabove,theRankenumerationdefinesafurthernestedstructureofitsown,calledValues.Thisstructureencapsulatesthefactthatmostcardshaveonevalue,buttheAcecardhastwovalues.TheValuesstructuredefinestwopropertiestorepresentthis:

first,oftypeInt

second,oftypeInt?,or“optionalInt”

Rankalsodefinesacomputedproperty,values,whichreturnsaninstanceoftheValuesstructure.ThiscomputedpropertyconsiderstherankofthecardandinitializesanewValuesinstancewithappropriatevaluesbasedonitsrank.Itusesspecialvaluesforjack,queen,king,andace.Forthenumericcards,itusestherank’srawIntvalue.

TheBlackjackCardstructureitselfhastwoproperties—rankandsuit.Italsodefinesacomputedpropertycalleddescription,whichusesthevaluesstoredinrankandsuittobuildadescriptionofthenameandvalueofthecard.Thedescriptionpropertyusesoptionalbindingtocheckwhetherthereisasecondvaluetodisplay,andifso,insertsadditionaldescriptiondetailforthatsecondvalue.

BecauseBlackjackCardisastructurewithnocustominitializers,ithasanimplicitmemberwiseinitializer,asdescribedinMemberwiseInitializersforStructureTypes.YoucanusethisinitializertoinitializeanewconstantcalledtheAceOfSpades:

1 lettheAceOfSpades=BlackjackCard(rank:.ace,suit:.spades)

Page 372: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 print("theAceOfSpades:\(theAceOfSpades.description)")

3 //Prints"theAceOfSpades:suitis♠,valueis1or11"

EventhoughRankandSuitarenestedwithinBlackjackCard,theirtypecanbeinferredfromcontext,andsotheinitializationofthisinstanceisabletorefertotheenumerationcasesbytheircasenames(.aceand.spades)alone.Intheexampleabove,thedescriptionpropertycorrectlyreportsthattheAceofSpadeshasavalueof1or11.

ReferringtoNestedTypes

Touseanestedtypeoutsideofitsdefinitioncontext,prefixitsnamewiththenameofthetypeitisnestedwithin:

1 letheartsSymbol=BlackjackCard.Suit.hearts.rawValue

2 //heartsSymbolis"♡"

Fortheexampleabove,thisenablesthenamesofSuit,Rank,andValuestobekeptdeliberatelyshort,becausetheirnamesarenaturallyqualifiedbythecontextinwhichtheyaredefined.

Page 373: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Extensions

Extensionsaddnewfunctionalitytoanexistingclass,structure,enumeration,orprotocoltype.Thisincludestheabilitytoextendtypesforwhichyoudonothaveaccesstotheoriginalsourcecode(knownasretroactivemodeling).ExtensionsaresimilartocategoriesinObjective-C.(UnlikeObjective-Ccategories,Swiftextensionsdonothavenames.)

ExtensionsinSwiftcan:

Addcomputedinstancepropertiesandcomputedtypeproperties

Defineinstancemethodsandtypemethods

Providenewinitializers

Definesubscripts

Defineandusenewnestedtypes

Makeanexistingtypeconformtoaprotocol

InSwift,youcanevenextendaprotocoltoprovideimplementationsofitsrequirementsoraddadditionalfunctionalitythatconformingtypescantakeadvantageof.Formoredetails,seeProtocolExtensions.

NOTE

Extensionscanaddnewfunctionalitytoatype,buttheycannotoverrideexistingfunctionality.

ExtensionSyntax

Declareextensionswiththeextensionkeyword:

Page 374: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 extensionSomeType{

2 //newfunctionalitytoaddtoSomeTypegoeshere

3 }

Anextensioncanextendanexistingtypetomakeitadoptoneormoreprotocols.Toaddprotocolconformance,youwritetheprotocolnamesthesamewayasyouwritethemforaclassorstructure:

1 extensionSomeType:SomeProtocol,AnotherProtocol{

2 //implementationofprotocolrequirementsgoeshere

3 }

AddingprotocolconformanceinthiswayisdescribedinAddingProtocolConformancewithanExtension.

Anextensioncanbeusedtoextendanexistinggenerictype,asdescribedinExtendingaGenericType.Youcanalsoextendagenerictypetoconditionallyaddfunctionality,asdescribedinExtensionswithaGenericWhereClause.

NOTE

Ifyoudefineanextensiontoaddnewfunctionalitytoanexistingtype,thenewfunctionalitywillbeavailableonallexistinginstancesofthattype,eveniftheywerecreatedbeforetheextensionwasdefined.

ComputedProperties

Extensionscanaddcomputedinstancepropertiesandcomputedtypepropertiestoexistingtypes.ThisexampleaddsfivecomputedinstancepropertiestoSwift’sbuilt-inDoubletype,toprovidebasicsupportforworkingwithdistanceunits:

1 extensionDouble{

2 varkm:Double{returnself*1_000.0}

3 varm:Double{returnself}

Page 375: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 varcm:Double{returnself/100.0}

5 varmm:Double{returnself/1_000.0}

6 varft:Double{returnself/3.28084}

7 }

8 letoneInch=25.4.mm

9 print("Oneinchis\(oneInch)meters")

10 //Prints"Oneinchis0.0254meters"

11 letthreeFeet=3.ft

12 print("Threefeetis\(threeFeet)meters")

13 //Prints"Threefeetis0.914399970739201meters"

ThesecomputedpropertiesexpressthataDoublevalueshouldbeconsideredasacertainunitoflength.Althoughtheyareimplementedascomputedproperties,thenamesofthesepropertiescanbeappendedtoafloating-pointliteralvaluewithdotsyntax,asawaytousethatliteralvaluetoperformdistanceconversions.

Inthisexample,aDoublevalueof1.0isconsideredtorepresent“onemeter”.Thisiswhythemcomputedpropertyreturnsself—theexpression1.misconsideredtocalculateaDoublevalueof1.0.

Otherunitsrequiresomeconversiontobeexpressedasavaluemeasuredinmeters.Onekilometeristhesameas1,000meters,sothekmcomputedpropertymultipliesthevalueby1_000.00toconvertintoanumberexpressedinmeters.Similarly,thereare3.28084feetinameter,andsotheftcomputedpropertydividestheunderlyingDoublevalueby3.28084,toconvertitfromfeettometers.

Thesepropertiesareread-onlycomputedproperties,andsotheyareexpressedwithoutthegetkeyword,forbrevity.TheirreturnvalueisoftypeDouble,andcanbeusedwithinmathematicalcalculationswhereveraDoubleisaccepted:

1 letaMarathon=42.km+195.m

2 print("Amarathonis\(aMarathon)meterslong")

3 //Prints"Amarathonis42195.0meterslong"

Page 376: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Extensionscanaddnewcomputedproperties,buttheycannotaddstoredproperties,oraddpropertyobserverstoexistingproperties.

Initializers

Extensionscanaddnewinitializerstoexistingtypes.Thisenablesyoutoextendothertypestoacceptyourowncustomtypesasinitializerparameters,ortoprovideadditionalinitializationoptionsthatwerenotincludedaspartofthetype’soriginalimplementation.

Extensionscanaddnewconvenienceinitializerstoaclass,buttheycannotaddnewdesignatedinitializersordeinitializerstoaclass.Designatedinitializersanddeinitializersmustalwaysbeprovidedbytheoriginalclassimplementation.

Ifyouuseanextensiontoaddaninitializertoavaluetypethatprovidesdefaultvaluesforallofitsstoredpropertiesanddoesnotdefineanycustominitializers,youcancallthedefaultinitializerandmemberwiseinitializerforthatvaluetypefromwithinyourextension’sinitializer.Thiswouldn’tbethecaseifyouhadwrittentheinitializeraspartofthevaluetype’soriginalimplementation,asdescribedinInitializerDelegationforValueTypes.

Ifyouuseanextensiontoaddaninitializertoastructurethatwasdeclaredinanothermodule,thenewinitializercan’taccessselfuntilitcallsaninitializerfromthedefiningmodule.

TheexamplebelowdefinesacustomRectstructuretorepresentageometricrectangle.TheexamplealsodefinestwosupportingstructurescalledSizeandPoint,bothofwhichprovidedefaultvaluesof0.0foralloftheirproperties:

1 structSize{

2 varwidth=0.0,height=0.0

3 }

4 structPoint{

Page 377: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 varx=0.0,y=0.0

6 }

7 structRect{

8 varorigin=Point()

9 varsize=Size()

10 }

BecausetheRectstructureprovidesdefaultvaluesforallofitsproperties,itreceivesadefaultinitializerandamemberwiseinitializerautomatically,asdescribedinDefaultInitializers.TheseinitializerscanbeusedtocreatenewRectinstances:

1 letdefaultRect=Rect()

2 letmemberwiseRect=Rect(origin:Point(x:2.0,y:2.0),

3 size:Size(width:5.0,height:5.0))

YoucanextendtheRectstructuretoprovideanadditionalinitializerthattakesaspecificcenterpointandsize:

1 extensionRect{

2 init(center:Point,size:Size){

3 letoriginX=center.x-(size.width/2)

4 letoriginY=center.y-(size.height/2)

5 self.init(origin:Point(x:originX,y:originY),size:

size)

6 }

7 }

Thisnewinitializerstartsbycalculatinganappropriateoriginpointbasedontheprovidedcenterpointandsizevalue.Theinitializerthencallsthestructure’sautomaticmemberwiseinitializerinit(origin:size:),whichstorestheneworiginandsizevaluesintheappropriateproperties:

Page 378: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letcenterRect=Rect(center:Point(x:4.0,y:4.0),

2 size:Size(width:3.0,height:3.0))

3 //centerRect'soriginis(2.5,2.5)anditssizeis(3.0,3.0)

NOTE

Ifyouprovideanewinitializerwithanextension,youarestillresponsibleformakingsurethateachinstanceisfullyinitializedoncetheinitializercompletes.

Methods

Extensionscanaddnewinstancemethodsandtypemethodstoexistingtypes.ThefollowingexampleaddsanewinstancemethodcalledrepetitionstotheInttype:

1 extensionInt{

2 funcrepetitions(task:()->Void){

3 for_in0..<self{

4 task()

5 }

6 }

7 }

Therepetitions(task:)methodtakesasingleargumentoftype()->Void,whichindicatesafunctionthathasnoparametersanddoesnotreturnavalue.

Afterdefiningthisextension,youcancalltherepetitions(task:)methodonanyintegertoperformataskthatmanynumberoftimes:

1 3.repetitions{

2 print("Hello!")

3 }

Page 379: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 //Hello!

5 //Hello!

6 //Hello!

MutatingInstanceMethodsInstancemethodsaddedwithanextensioncanalsomodify(ormutate)theinstanceitself.Structureandenumerationmethodsthatmodifyselforitspropertiesmustmarktheinstancemethodasmutating,justlikemutatingmethodsfromanoriginalimplementation.

TheexamplebelowaddsanewmutatingmethodcalledsquaretoSwift’sInttype,whichsquarestheoriginalvalue:

1 extensionInt{

2 mutatingfuncsquare(){

3 self=self*self

4 }

5 }

6 varsomeInt=3

7 someInt.square()

8 //someIntisnow9

Subscripts

Extensionscanaddnewsubscriptstoanexistingtype.ThisexampleaddsanintegersubscripttoSwift’sbuilt-inInttype.Thissubscript[n]returnsthedecimaldigitnplacesinfromtherightofthenumber:

123456789[0]returns9

123456789[1]returns8

Page 380: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

…andsoon:

1 extensionInt{

2 subscript(digitIndex:Int)->Int{

3 vardecimalBase=1

4 for_in0..<digitIndex{

5 decimalBase*=10

6 }

7 return(self/decimalBase)%10

8 }

9 }

10 746381295[0]

11 //returns5

12 746381295[1]

13 //returns9

14 746381295[2]

15 //returns2

16 746381295[8]

17 //returns7

IftheIntvaluedoesnothaveenoughdigitsfortherequestedindex,thesubscriptimplementationreturns0,asifthenumberhadbeenpaddedwithzerostotheleft:

1 746381295[9]

2 //returns0,asifyouhadrequested:

3 0746381295[9]

NestedTypes

Page 381: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Extensionscanaddnewnestedtypestoexistingclasses,structures,andenumerations:

1 extensionInt{

2 enumKind{

3 casenegative,zero,positive

4 }

5 varkind:Kind{

6 switchself{

7 case0:

8 return.zero

9 caseletxwherex>0:

10 return.positive

11 default:

12 return.negative

13 }

14 }

15 }

ThisexampleaddsanewnestedenumerationtoInt.Thisenumeration,calledKind,expressesthekindofnumberthataparticularintegerrepresents.Specifically,itexpresseswhetherthenumberisnegative,zero,orpositive.

ThisexamplealsoaddsanewcomputedinstancepropertytoInt,calledkind,whichreturnstheappropriateKindenumerationcaseforthatinteger.

ThenestedenumerationcannowbeusedwithanyIntvalue:

1 funcprintIntegerKinds(_numbers:[Int]){

2 fornumberinnumbers{

3 switchnumber.kind{

4 case.negative:

Page 382: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 print("-",terminator:"")

6 case.zero:

7 print("0",terminator:"")

8 case.positive:

9 print("+",terminator:"")

10 }

11 }

12 print("")

13 }

14 printIntegerKinds([3,19,-27,0,-6,0,7])

15 //Prints"++-0-0+"

Thisfunction,printIntegerKinds(_:),takesaninputarrayofIntvaluesanditeratesoverthosevaluesinturn.Foreachintegerinthearray,thefunctionconsidersthekindcomputedpropertyforthatinteger,andprintsanappropriatedescription.

NOTE

number.kindisalreadyknowntobeoftypeInt.Kind.Becauseofthis,alloftheInt.Kindcasevaluescanbewritteninshorthandforminsidetheswitchstatement,suchas.negativeratherthanInt.Kind.negative.

Page 383: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Protocols

Aprotocoldefinesablueprintofmethods,properties,andotherrequirementsthatsuitaparticulartaskorpieceoffunctionality.Theprotocolcanthenbeadoptedbyaclass,structure,orenumerationtoprovideanactualimplementationofthoserequirements.Anytypethatsatisfiestherequirementsofaprotocolissaidtoconformtothatprotocol.

Inadditiontospecifyingrequirementsthatconformingtypesmustimplement,youcanextendaprotocoltoimplementsomeoftheserequirementsortoimplementadditionalfunctionalitythatconformingtypescantakeadvantageof.

ProtocolSyntax

Youdefineprotocolsinaverysimilarwaytoclasses,structures,andenumerations:

1 protocolSomeProtocol{

2 //protocoldefinitiongoeshere

3 }

Customtypesstatethattheyadoptaparticularprotocolbyplacingtheprotocol’snameafterthetype’sname,separatedbyacolon,aspartoftheirdefinition.Multipleprotocolscanbelisted,andareseparatedbycommas:

1 structSomeStructure:FirstProtocol,AnotherProtocol{

2 //structuredefinitiongoeshere

3 }

Ifaclasshasasuperclass,listthesuperclassnamebeforeanyprotocolsitadopts,followedbyacomma:

Page 384: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 classSomeClass:SomeSuperclass,FirstProtocol,AnotherProtocol

{

2 //classdefinitiongoeshere

3 }

PropertyRequirements

Aprotocolcanrequireanyconformingtypetoprovideaninstancepropertyortypepropertywithaparticularnameandtype.Theprotocoldoesn’tspecifywhetherthepropertyshouldbeastoredpropertyoracomputedproperty—itonlyspecifiestherequiredpropertynameandtype.Theprotocolalsospecifieswhethereachpropertymustbegettableorgettableandsettable.

Ifaprotocolrequiresapropertytobegettableandsettable,thatpropertyrequirementcan’tbefulfilledbyaconstantstoredpropertyoraread-onlycomputedproperty.Iftheprotocolonlyrequiresapropertytobegettable,therequirementcanbesatisfiedbyanykindofproperty,andit’svalidforthepropertytobealsosettableifthisisusefulforyourowncode.

Propertyrequirementsarealwaysdeclaredasvariableproperties,prefixedwiththevarkeyword.Gettableandsettablepropertiesareindicatedbywriting{getset}aftertheirtypedeclaration,andgettablepropertiesareindicatedbywriting{get}.

1 protocolSomeProtocol{

2 varmustBeSettable:Int{getset}

3 vardoesNotNeedToBeSettable:Int{get}

4 }

Alwaysprefixtypepropertyrequirementswiththestatickeywordwhenyoudefinetheminaprotocol.Thisrulepertainseventhoughtypepropertyrequirementscanbeprefixedwiththeclassorstatickeywordwhenimplementedbyaclass:

Page 385: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 protocolAnotherProtocol{

2 staticvarsomeTypeProperty:Int{getset}

3 }

Here’sanexampleofaprotocolwithasingleinstancepropertyrequirement:

1 protocolFullyNamed{

2 varfullName:String{get}

3 }

TheFullyNamedprotocolrequiresaconformingtypetoprovideafullyqualifiedname.Theprotocoldoesn’tspecifyanythingelseaboutthenatureoftheconformingtype—itonlyspecifiesthatthetypemustbeabletoprovideafullnameforitself.TheprotocolstatesthatanyFullyNamedtypemusthaveagettableinstancepropertycalledfullName,whichisoftypeString.

Here’sanexampleofasimplestructurethatadoptsandconformstotheFullyNamedprotocol:

1 structPerson:FullyNamed{

2 varfullName:String

3 }

4 letjohn=Person(fullName:"JohnAppleseed")

5 //john.fullNameis"JohnAppleseed"

ThisexampledefinesastructurecalledPerson,whichrepresentsaspecificnamedperson.ItstatesthatitadoptstheFullyNamedprotocolaspartofthefirstlineofitsdefinition.

EachinstanceofPersonhasasinglestoredpropertycalledfullName,whichisoftypeString.ThismatchesthesinglerequirementoftheFullyNamedprotocol,andmeansthatPersonhascorrectlyconformedtotheprotocol.(Swiftreportsanerroratcompile-timeifaprotocolrequirementisnotfulfilled.)

Here’samorecomplexclass,whichalsoadoptsandconformstotheFullyNamed

Page 386: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

protocol:

1 classStarship:FullyNamed{

2 varprefix:String?

3 varname:String

4 init(name:String,prefix:String?=nil){

5 self.name=name

6 self.prefix=prefix

7 }

8 varfullName:String{

9 return(prefix!=nil?prefix!+"":"")+name

10 }

11 }

12 varncc1701=Starship(name:"Enterprise",prefix:"USS")

13 //ncc1701.fullNameis"USSEnterprise"

ThisclassimplementsthefullNamepropertyrequirementasacomputedread-onlypropertyforastarship.EachStarshipclassinstancestoresamandatorynameandanoptionalprefix.ThefullNamepropertyusestheprefixvalueifitexists,andprependsittothebeginningofnametocreateafullnameforthestarship.

MethodRequirements

Protocolscanrequirespecificinstancemethodsandtypemethodstobeimplementedbyconformingtypes.Thesemethodsarewrittenaspartoftheprotocol’sdefinitioninexactlythesamewayasfornormalinstanceandtypemethods,butwithoutcurlybracesoramethodbody.Variadicparametersareallowed,subjecttothesamerulesasfornormalmethods.Defaultvalues,however,can’tbespecifiedformethodparameterswithinaprotocol’sdefinition.

Aswithtypepropertyrequirements,youalwaysprefixtypemethod

Page 387: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

requirementswiththestatickeywordwhenthey’redefinedinaprotocol.Thisistrueeventhoughtypemethodrequirementsareprefixedwiththeclassorstatickeywordwhenimplementedbyaclass:

1 protocolSomeProtocol{

2 staticfuncsomeTypeMethod()

3 }

Thefollowingexampledefinesaprotocolwithasingleinstancemethodrequirement:

1 protocolRandomNumberGenerator{

2 funcrandom()->Double

3 }

Thisprotocol,RandomNumberGenerator,requiresanyconformingtypetohaveaninstancemethodcalledrandom,whichreturnsaDoublevaluewheneverit’scalled.Althoughit’snotspecifiedaspartoftheprotocol,it’sassumedthatthisvaluewillbeanumberfrom0.0upto(butnotincluding)1.0.

TheRandomNumberGeneratorprotocoldoesn’tmakeanyassumptionsabouthoweachrandomnumberwillbegenerated—itsimplyrequiresthegeneratortoprovideastandardwaytogenerateanewrandomnumber.

Here’sanimplementationofaclassthatadoptsandconformstotheRandomNumberGeneratorprotocol.Thisclassimplementsapseudorandomnumbergeneratoralgorithmknownasalinearcongruentialgenerator:

1 classLinearCongruentialGenerator:RandomNumberGenerator{

2 varlastRandom=42.0

3 letm=139968.0

4 leta=3877.0

5 letc=29573.0

6 funcrandom()->Double{

Page 388: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

7 lastRandom=((lastRandom*a+c)

8 .truncatingRemainder(dividingBy:m))

9 returnlastRandom/m

10 }

11 }

12 letgenerator=LinearCongruentialGenerator()

13 print("Here'sarandomnumber:\(generator.random())")

14 //Prints"Here'sarandomnumber:0.3746499199817101"

15 print("Andanotherone:\(generator.random())")

16 //Prints"Andanotherone:0.729023776863283"

MutatingMethodRequirements

It’ssometimesnecessaryforamethodtomodify(ormutate)theinstanceitbelongsto.Forinstancemethodsonvaluetypes(thatis,structuresandenumerations)youplacethemutatingkeywordbeforeamethod’sfunckeywordtoindicatethatthemethodisallowedtomodifytheinstanceitbelongstoandanypropertiesofthatinstance.ThisprocessisdescribedinModifyingValueTypesfromWithinInstanceMethods.

Ifyoudefineaprotocolinstancemethodrequirementthatisintendedtomutateinstancesofanytypethatadoptstheprotocol,markthemethodwiththemutatingkeywordaspartoftheprotocol’sdefinition.Thisenablesstructuresandenumerationstoadopttheprotocolandsatisfythatmethodrequirement.

NOTE

Ifyoumarkaprotocolinstancemethodrequirementasmutating,youdon’tneedtowritethemutatingkeywordwhenwritinganimplementationofthatmethodforaclass.Themutatingkeywordisonlyusedbystructuresandenumerations.

TheexamplebelowdefinesaprotocolcalledTogglable,whichdefinesasingleinstancemethodrequirementcalledtoggle.Asitsnamesuggests,thetoggle()

Page 389: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

methodisintendedtotoggleorinvertthestateofanyconformingtype,typicallybymodifyingapropertyofthattype.

Thetoggle()methodismarkedwiththemutatingkeywordaspartoftheTogglableprotocoldefinition,toindicatethatthemethodisexpectedtomutatethestateofaconforminginstancewhenit’scalled:

1 protocolTogglable{

2 mutatingfunctoggle()

3 }

IfyouimplementtheTogglableprotocolforastructureorenumeration,thatstructureorenumerationcanconformtotheprotocolbyprovidinganimplementationofthetoggle()methodthatisalsomarkedasmutating.

TheexamplebelowdefinesanenumerationcalledOnOffSwitch.Thisenumerationtogglesbetweentwostates,indicatedbytheenumerationcasesonandoff.Theenumeration’stoggleimplementationismarkedasmutating,tomatchtheTogglableprotocol’srequirements:

1 enumOnOffSwitch:Togglable{

2 caseoff,on

3 mutatingfunctoggle(){

4 switchself{

5 case.off:

6 self=.on

7 case.on:

8 self=.off

9 }

10 }

11 }

12 varlightSwitch=OnOffSwitch.off

13 lightSwitch.toggle()

Page 390: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

14 //lightSwitchisnowequalto.on

InitializerRequirements

Protocolscanrequirespecificinitializerstobeimplementedbyconformingtypes.Youwritetheseinitializersaspartoftheprotocol’sdefinitioninexactlythesamewayasfornormalinitializers,butwithoutcurlybracesoraninitializerbody:

1 protocolSomeProtocol{

2 init(someParameter:Int)

3 }

ClassImplementationsofProtocolInitializerRequirementsYoucanimplementaprotocolinitializerrequirementonaconformingclassaseitheradesignatedinitializeroraconvenienceinitializer.Inbothcases,youmustmarktheinitializerimplementationwiththerequiredmodifier:

1 classSomeClass:SomeProtocol{

2 requiredinit(someParameter:Int){

3 //initializerimplementationgoeshere

4 }

5 }

Theuseoftherequiredmodifierensuresthatyouprovideanexplicitorinheritedimplementationoftheinitializerrequirementonallsubclassesoftheconformingclass,suchthattheyalsoconformtotheprotocol.

Formoreinformationonrequiredinitializers,seeRequiredInitializers.

NOTE

Page 391: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youdon’tneedtomarkprotocolinitializerimplementationswiththerequiredmodifieronclassesthataremarkedwiththefinalmodifier,becausefinalclassescan’tsubclassed.Formoreaboutthefinalmodifier,seePreventingOverrides.

Ifasubclassoverridesadesignatedinitializerfromasuperclass,andalsoimplementsamatchinginitializerrequirementfromaprotocol,marktheinitializerimplementationwithboththerequiredandoverridemodifiers:

1 protocolSomeProtocol{

2 init()

3 }

4

5 classSomeSuperClass{

6 init(){

7 //initializerimplementationgoeshere

8 }

9 }

10

11 classSomeSubClass:SomeSuperClass,SomeProtocol{

12 //"required"fromSomeProtocolconformance;"override"

fromSomeSuperClass

13 requiredoverrideinit(){

14 //initializerimplementationgoeshere

15 }

16 }

FailableInitializerRequirementsProtocolscandefinefailableinitializerrequirementsforconformingtypes,asdefinedinFailableInitializers.

Afailableinitializerrequirementcanbesatisfiedbyafailableornonfailable

Page 392: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

initializeronaconformingtype.Anonfailableinitializerrequirementcanbesatisfiedbyanonfailableinitializeroranimplicitlyunwrappedfailableinitializer.

ProtocolsasTypes

Protocolsdon’tactuallyimplementanyfunctionalitythemselves.Nonetheless,youcanuseprotocolsasafullyfledgedtypesinyourcode.Usingaprotocolasatypeissometimescalledanexistentialtype,whichcomesfromthephrase“thereexistsatypeTsuchthatTconformstotheprotocol”.

Youcanuseaprotocolinmanyplaceswhereothertypesareallowed,including:

Asaparametertypeorreturntypeinafunction,method,orinitializer

Asthetypeofaconstant,variable,orproperty

Asthetypeofitemsinanarray,dictionary,orothercontainer

NOTE

Becauseprotocolsaretypes,begintheirnameswithacapitalletter(suchasFullyNamedandRandomNumberGenerator)tomatchthenamesofothertypesinSwift(suchasInt,String,andDouble).

Here’sanexampleofaprotocolusedasatype:

1 classDice{

2 letsides:Int

3 letgenerator:RandomNumberGenerator

4 init(sides:Int,generator:RandomNumberGenerator){

5 self.sides=sides

6 self.generator=generator

7 }

Page 393: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 funcroll()->Int{

9 returnInt(generator.random()*Double(sides))+1

10 }

11 }

ThisexampledefinesanewclasscalledDice,whichrepresentsann-sideddiceforuseinaboardgame.Diceinstanceshaveanintegerpropertycalledsides,whichrepresentshowmanysidestheyhave,andapropertycalledgenerator,whichprovidesarandomnumbergeneratorfromwhichtocreatedicerollvalues.

ThegeneratorpropertyisoftypeRandomNumberGenerator.Therefore,youcansetittoaninstanceofanytypethatadoptstheRandomNumberGeneratorprotocol.Nothingelseisrequiredoftheinstanceyouassigntothisproperty,exceptthattheinstancemustadopttheRandomNumberGeneratorprotocol.BecauseitstypeisRandomNumberGenerator,codeinsidetheDiceclasscanonlyinteractwithgeneratorinwaysthatapplytoallgeneratorsthatconformtothisprotocol.Thatmeansitcan’tuseanymethodsorpropertiesthataredefinedbytheunderlyingtypeofthegenerator.However,youcandowncastfromaprotocoltypetoanunderlyingtypeinthesamewayyoucandowncastfromasuperclasstoasubclass,asdiscussedinDowncasting.

Dicealsohasaninitializer,tosetupitsinitialstate.Thisinitializerhasaparametercalledgenerator,whichisalsooftypeRandomNumberGenerator.YoucanpassavalueofanyconformingtypeintothisparameterwheninitializinganewDiceinstance.

Diceprovidesoneinstancemethod,roll,whichreturnsanintegervaluebetween1andthenumberofsidesonthedice.Thismethodcallsthegenerator’srandom()methodtocreateanewrandomnumberbetween0.0and1.0,andusesthisrandomnumbertocreateadicerollvaluewithinthecorrectrange.BecausegeneratorisknowntoadoptRandomNumberGenerator,it’sguaranteedtohavearandom()methodtocall.

Here’showtheDiceclasscanbeusedtocreateasix-sideddicewithaLinearCongruentialGeneratorinstanceasitsrandomnumbergenerator:

Page 394: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 vard6=Dice(sides:6,generator:

LinearCongruentialGenerator())

2 for_in1...5{

3 print("Randomdicerollis\(d6.roll())")

4 }

5 //Randomdicerollis3

6 //Randomdicerollis5

7 //Randomdicerollis4

8 //Randomdicerollis5

9 //Randomdicerollis4

Delegation

Delegationisadesignpatternthatenablesaclassorstructuretohandoff(ordelegate)someofitsresponsibilitiestoaninstanceofanothertype.Thisdesignpatternisimplementedbydefiningaprotocolthatencapsulatesthedelegatedresponsibilities,suchthataconformingtype(knownasadelegate)isguaranteedtoprovidethefunctionalitythathasbeendelegated.Delegationcanbeusedtorespondtoaparticularaction,ortoretrievedatafromanexternalsourcewithoutneedingtoknowtheunderlyingtypeofthatsource.

Theexamplebelowdefinestwoprotocolsforusewithdice-basedboardgames:

1 protocolDiceGame{

2 vardice:Dice{get}

3 funcplay()

4 }

5 protocolDiceGameDelegate:AnyObject{

6 funcgameDidStart(_game:DiceGame)

7 funcgame(_game:DiceGame,didStartNewTurnWithDiceRoll

Page 395: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

diceRoll:Int)

8 funcgameDidEnd(_game:DiceGame)

9 }

TheDiceGameprotocolisaprotocolthatcanbeadoptedbyanygamethatinvolvesdice.

TheDiceGameDelegateprotocolcanbeadoptedtotracktheprogressofaDiceGame.Topreventstrongreferencecycles,delegatesaredeclaredasweakreferences.Forinformationaboutweakreferences,seeStrongReferenceCyclesBetweenClassInstances.Markingtheprotocolasclass-onlyletstheSnakesAndLaddersclasslaterinthischapterdeclarethatitsdelegatemustuseaweakreference.Aclass-onlyprotocolismarkedbyitsinheritancefromAnyObject,asdiscussedinClass-OnlyProtocols.

Here’saversionoftheSnakesandLaddersgameoriginallyintroducedinControlFlow.ThisversionisadaptedtouseaDiceinstanceforitsdice-rolls;toadopttheDiceGameprotocol;andtonotifyaDiceGameDelegateaboutitsprogress:

1 classSnakesAndLadders:DiceGame{

2 letfinalSquare=25

3 letdice=Dice(sides:6,generator:

LinearCongruentialGenerator())

4 varsquare=0

5 varboard:[Int]

6 init(){

7 board=Array(repeating:0,count:finalSquare+1)

8 board[03]=+08;board[06]=+11;board[09]=+09;

board[10]=+02

9 board[14]=-10;board[19]=-11;board[22]=-02;

board[24]=-08

10 }

11 weakvardelegate:DiceGameDelegate?

Page 396: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

12 funcplay(){

13 square=0

14 delegate?.gameDidStart(self)

15 gameLoop:whilesquare!=finalSquare{

16 letdiceRoll=dice.roll()

17 delegate?.game(self,didStartNewTurnWithDiceRoll:

diceRoll)

18 switchsquare+diceRoll{

19 casefinalSquare:

20 breakgameLoop

21 caseletnewSquarewherenewSquare>finalSquare:

22 continuegameLoop

23 default:

24 square+=diceRoll

25 square+=board[square]

26 }

27 }

28 delegate?.gameDidEnd(self)

29 }

30 }

ForadescriptionoftheSnakesandLaddersgameplay,seeBreak.

ThisversionofthegameiswrappedupasaclasscalledSnakesAndLadders,whichadoptstheDiceGameprotocol.Itprovidesagettabledicepropertyandaplay()methodinordertoconformtotheprotocol.(Thedicepropertyisdeclaredasaconstantpropertybecauseitdoesn’tneedtochangeafterinitialization,andtheprotocolonlyrequiresthatitmustbegettable.)

TheSnakesandLaddersgameboardsetuptakesplacewithintheclass’sinit()initializer.Allgamelogicismovedintotheprotocol’splaymethod,whichusestheprotocol’srequireddicepropertytoprovideitsdicerollvalues.

Page 397: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NotethatthedelegatepropertyisdefinedasanoptionalDiceGameDelegate,becauseadelegateisn’trequiredinordertoplaythegame.Becauseit’sofanoptionaltype,thedelegatepropertyisautomaticallysettoaninitialvalueofnil.Thereafter,thegameinstantiatorhastheoptiontosetthepropertytoasuitabledelegate.BecausetheDiceGameDelegateprotocolisclass-only,youcandeclarethedelegatetobeweaktopreventreferencecycles.

DiceGameDelegateprovidesthreemethodsfortrackingtheprogressofagame.Thesethreemethodshavebeenincorporatedintothegamelogicwithintheplay()methodabove,andarecalledwhenanewgamestarts,anewturnbegins,orthegameends.

BecausethedelegatepropertyisanoptionalDiceGameDelegate,theplay()methodusesoptionalchainingeachtimeitcallsamethodonthedelegate.Ifthedelegatepropertyisnil,thesedelegatecallsfailgracefullyandwithouterror.Ifthedelegatepropertyisnon-nil,thedelegatemethodsarecalled,andarepassedtheSnakesAndLaddersinstanceasaparameter.

ThisnextexampleshowsaclasscalledDiceGameTracker,whichadoptstheDiceGameDelegateprotocol:

1 classDiceGameTracker:DiceGameDelegate{

2 varnumberOfTurns=0

3 funcgameDidStart(_game:DiceGame){

4 numberOfTurns=0

5 ifgameisSnakesAndLadders{

6 print("StartedanewgameofSnakesandLadders")

7 }

8 print("Thegameisusinga\(game.dice.sides)-sided

dice")

9 }

10 funcgame(_game:DiceGame,didStartNewTurnWithDiceRoll

diceRoll:Int){

11 numberOfTurns+=1

Page 398: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

12 print("Rolleda\(diceRoll)")

13 }

14 funcgameDidEnd(_game:DiceGame){

15 print("Thegamelastedfor\(numberOfTurns)turns")

16 }

17 }

DiceGameTrackerimplementsallthreemethodsrequiredbyDiceGameDelegate.Itusesthesemethodstokeeptrackofthenumberofturnsagamehastaken.ItresetsanumberOfTurnspropertytozerowhenthegamestarts,incrementsiteachtimeanewturnbegins,andprintsoutthetotalnumberofturnsoncethegamehasended.

TheimplementationofgameDidStart(_:)shownaboveusesthegameparametertoprintsomeintroductoryinformationaboutthegamethatisabouttobeplayed.ThegameparameterhasatypeofDiceGame,notSnakesAndLadders,andsogameDidStart(_:)canaccessanduseonlymethodsandpropertiesthatareimplementedaspartoftheDiceGameprotocol.However,themethodisstillabletousetypecastingtoquerythetypeoftheunderlyinginstance.Inthisexample,itcheckswhethergameisactuallyaninstanceofSnakesAndLaddersbehindthescenes,andprintsanappropriatemessageifso.

ThegameDidStart(_:)methodalsoaccessesthedicepropertyofthepassedgameparameter.BecausegameisknowntoconformtotheDiceGameprotocol,it’sguaranteedtohaveadiceproperty,andsothegameDidStart(_:)methodisabletoaccessandprintthedice’ssidesproperty,regardlessofwhatkindofgameisbeingplayed.

Here’showDiceGameTrackerlooksinaction:

1 lettracker=DiceGameTracker()

2 letgame=SnakesAndLadders()

3 game.delegate=tracker

4 game.play()

5 //StartedanewgameofSnakesandLadders

Page 399: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 //Thegameisusinga6-sideddice

7 //Rolleda3

8 //Rolleda5

9 //Rolleda4

10 //Rolleda5

11 //Thegamelastedfor4turns

AddingProtocolConformancewithanExtension

Youcanextendanexistingtypetoadoptandconformtoanewprotocol,evenifyoudon’thaveaccesstothesourcecodefortheexistingtype.Extensionscanaddnewproperties,methods,andsubscriptstoanexistingtype,andarethereforeabletoaddanyrequirementsthataprotocolmaydemand.Formoreaboutextensions,seeExtensions.

NOTE

Existinginstancesofatypeautomaticallyadoptandconformtoaprotocolwhenthatconformanceisaddedtotheinstance’stypeinanextension.

Forexample,thisprotocol,calledTextRepresentable,canbeimplementedbyanytypethathasawaytoberepresentedastext.Thismightbeadescriptionofitself,oratextversionofitscurrentstate:

1 protocolTextRepresentable{

2 vartextualDescription:String{get}

3 }

TheDiceclassfromabovecanbeextendedtoadoptandconformtoTextRepresentable:

1 extensionDice:TextRepresentable{

2 vartextualDescription:String{

Page 400: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 return"A\(sides)-sideddice"

4 }

5 }

ThisextensionadoptsthenewprotocolinexactlythesamewayasifDicehadprovideditinitsoriginalimplementation.Theprotocolnameisprovidedafterthetypename,separatedbyacolon,andanimplementationofallrequirementsoftheprotocolisprovidedwithintheextension’scurlybraces.

AnyDiceinstancecannowbetreatedasTextRepresentable:

1 letd12=Dice(sides:12,generator:

LinearCongruentialGenerator())

2 print(d12.textualDescription)

3 //Prints"A12-sideddice"

Similarly,theSnakesAndLaddersgameclasscanbeextendedtoadoptandconformtotheTextRepresentableprotocol:

1 extensionSnakesAndLadders:TextRepresentable{

2 vartextualDescription:String{

3 return"AgameofSnakesandLadderswith\

(finalSquare)squares"

4 }

5 }

6 print(game.textualDescription)

7 //Prints"AgameofSnakesandLadderswith25squares"

ConditionallyConformingtoaProtocolAgenerictypemaybeabletosatisfytherequirementsofaprotocolonlyundercertainconditions,suchaswhenthetype’sgenericparameterconformstotheprotocol.Youcanmakeagenerictypeconditionallyconformtoaprotocolby

Page 401: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

listingconstraintswhenextendingthetype.Writetheseconstraintsafterthenameoftheprotocolyou’readoptingbywritingagenericwhereclause.Formoreaboutgenericwhereclauses,seeGenericWhereClauses.

ThefollowingextensionmakesArrayinstancesconformtotheTextRepresentableprotocolwhenevertheystoreelementsofatypethatconformstoTextRepresentable.

1 extensionArray:TextRepresentablewhereElement:

TextRepresentable{

2 vartextualDescription:String{

3 letitemsAsText=self.map{$0.textualDescription}

4 return"["+itemsAsText.joined(separator:",")+"]"

5 }

6 }

7 letmyDice=[d6,d12]

8 print(myDice.textualDescription)

9 //Prints"[A6-sideddice,A12-sideddice]"

DeclaringProtocolAdoptionwithanExtensionIfatypealreadyconformstoalloftherequirementsofaprotocol,buthasnotyetstatedthatitadoptsthatprotocol,youcanmakeitadopttheprotocolwithanemptyextension:

1 structHamster{

2 varname:String

3 vartextualDescription:String{

4 return"Ahamsternamed\(name)"

5 }

6 }

7 extensionHamster:TextRepresentable{}

Page 402: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

InstancesofHamstercannowbeusedwhereverTextRepresentableistherequiredtype:

1 letsimonTheHamster=Hamster(name:"Simon")

2 letsomethingTextRepresentable:TextRepresentable=

simonTheHamster

3 print(somethingTextRepresentable.textualDescription)

4 //Prints"AhamsternamedSimon"

NOTE

Typesdon’tautomaticallyadoptaprotocoljustbysatisfyingitsrequirements.Theymustalwaysexplicitlydeclaretheiradoptionoftheprotocol.

CollectionsofProtocolTypes

Aprotocolcanbeusedasthetypetobestoredinacollectionsuchasanarrayoradictionary,asmentionedinProtocolsasTypes.ThisexamplecreatesanarrayofTextRepresentablethings:

letthings:[TextRepresentable]=[game,d12,simonTheHamster]

It’snowpossibletoiterateovertheitemsinthearray,andprinteachitem’stextualdescription:

1 forthinginthings{

2 print(thing.textualDescription)

3 }

4 //AgameofSnakesandLadderswith25squares

5 //A12-sideddice

6 //AhamsternamedSimon

Page 403: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NotethatthethingconstantisoftypeTextRepresentable.It’snotoftypeDice,orDiceGame,orHamster,eveniftheactualinstancebehindthescenesisofoneofthosetypes.Nonetheless,becauseit’softypeTextRepresentable,andanythingthatisTextRepresentableisknowntohaveatextualDescriptionproperty,it’ssafetoaccessthing.textualDescriptioneachtimethroughtheloop.

ProtocolInheritance

Aprotocolcaninheritoneormoreotherprotocolsandcanaddfurtherrequirementsontopoftherequirementsitinherits.Thesyntaxforprotocolinheritanceissimilartothesyntaxforclassinheritance,butwiththeoptiontolistmultipleinheritedprotocols,separatedbycommas:

1 protocolInheritingProtocol:SomeProtocol,AnotherProtocol{

2 //protocoldefinitiongoeshere

3 }

Here’sanexampleofaprotocolthatinheritstheTextRepresentableprotocolfromabove:

1 protocolPrettyTextRepresentable:TextRepresentable{

2 varprettyTextualDescription:String{get}

3 }

Thisexampledefinesanewprotocol,PrettyTextRepresentable,whichinheritsfromTextRepresentable.AnythingthatadoptsPrettyTextRepresentablemustsatisfyalloftherequirementsenforcedbyTextRepresentable,plustheadditionalrequirementsenforcedbyPrettyTextRepresentable.Inthisexample,PrettyTextRepresentableaddsasinglerequirementtoprovideagettablepropertycalledprettyTextualDescriptionthatreturnsaString.

TheSnakesAndLaddersclasscanbeextendedtoadoptandconformtoPrettyTextRepresentable:

Page 404: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 extensionSnakesAndLadders:PrettyTextRepresentable{

2 varprettyTextualDescription:String{

3 varoutput=textualDescription+":\n"

4 forindexin1...finalSquare{

5 switchboard[index]{

6 caseletladderwhereladder>0:

7 output+="▲"

8 caseletsnakewheresnake<0:

9 output+="▼"

10 default:

11 output+="○"

12 }

13 }

14 returnoutput

15 }

16 }

ThisextensionstatesthatitadoptsthePrettyTextRepresentableprotocolandprovidesanimplementationoftheprettyTextualDescriptionpropertyfortheSnakesAndLadderstype.AnythingthatisPrettyTextRepresentablemustalsobeTextRepresentable,andsotheimplementationofprettyTextualDescriptionstartsbyaccessingthetextualDescriptionpropertyfromtheTextRepresentableprotocoltobeginanoutputstring.Itappendsacolonandalinebreak,andusesthisasthestartofitsprettytextrepresentation.Ittheniteratesthroughthearrayofboardsquares,andappendsageometricshapetorepresentthecontentsofeachsquare:

Ifthesquare’svalueisgreaterthan0,it’sthebaseofaladder,andisrepresentedby▲.

Ifthesquare’svalueislessthan0,it’stheheadofasnake,andisrepresentedby▼.

Page 405: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Otherwise,thesquare’svalueis0,andit’sa“free”square,representedby○.

TheprettyTextualDescriptionpropertycannowbeusedtoprintaprettytextdescriptionofanySnakesAndLaddersinstance:

1 print(game.prettyTextualDescription)

2 //AgameofSnakesandLadderswith25squares:

3 //○○▲○○▲○○▲▲○○○▼○○○○▼○○▼○▼○

Class-OnlyProtocols

Youcanlimitprotocoladoptiontoclasstypes(andnotstructuresorenumerations)byaddingtheAnyObjectprotocoltoaprotocol’sinheritancelist.

1 protocolSomeClassOnlyProtocol:AnyObject,

SomeInheritedProtocol{

2 //class-onlyprotocoldefinitiongoeshere

3 }

Intheexampleabove,SomeClassOnlyProtocolcanonlybeadoptedbyclasstypes.It’sacompile-timeerrortowriteastructureorenumerationdefinitionthattriestoadoptSomeClassOnlyProtocol.

NOTE

Useaclass-onlyprotocolwhenthebehaviordefinedbythatprotocol’srequirementsassumesorrequiresthataconformingtypehasreferencesemanticsratherthanvaluesemantics.Formoreaboutreferenceandvaluesemantics,seeStructuresandEnumerationsAreValueTypesandClassesAreReferenceTypes.

ProtocolComposition

Page 406: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Itcanbeusefultorequireatypetoconformtomultipleprotocolsatthesametime.Youcancombinemultipleprotocolsintoasinglerequirementwithaprotocolcomposition.Protocolcompositionsbehaveasifyoudefinedatemporarylocalprotocolthathasthecombinedrequirementsofallprotocolsinthecomposition.Protocolcompositionsdon’tdefineanynewprotocoltypes.

ProtocolcompositionshavetheformSomeProtocol&AnotherProtocol.Youcanlistasmanyprotocolsasyouneed,separatingthemwithampersands(&).Inadditiontoitslistofprotocols,aprotocolcompositioncanalsocontainoneclasstype,whichyoucanusetospecifyarequiredsuperclass.

Here’sanexamplethatcombinestwoprotocolscalledNamedandAgedintoasingleprotocolcompositionrequirementonafunctionparameter:

1 protocolNamed{

2 varname:String{get}

3 }

4 protocolAged{

5 varage:Int{get}

6 }

7 structPerson:Named,Aged{

8 varname:String

9 varage:Int

10 }

11 funcwishHappyBirthday(tocelebrator:Named&Aged){

12 print("Happybirthday,\(celebrator.name),you're\

(celebrator.age)!")

13 }

14 letbirthdayPerson=Person(name:"Malcolm",age:21)

15 wishHappyBirthday(to:birthdayPerson)

16 //Prints"Happybirthday,Malcolm,you're21!"

Inthisexample,theNamedprotocolhasasinglerequirementforagettableString

Page 407: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

propertycalledname.TheAgedprotocolhasasinglerequirementforagettableIntpropertycalledage.BothprotocolsareadoptedbyastructurecalledPerson.

TheexamplealsodefinesawishHappyBirthday(to:)function.ThetypeofthecelebratorparameterisNamed&Aged,whichmeans“anytypethatconformstoboththeNamedandAgedprotocols.”Itdoesn’tmatterwhichspecifictypeispassedtothefunction,aslongasitconformstobothoftherequiredprotocols.

TheexamplethencreatesanewPersoninstancecalledbirthdayPersonandpassesthisnewinstancetothewishHappyBirthday(to:)function.BecausePersonconformstobothprotocols,thiscallisvalid,andthewishHappyBirthday(to:)functioncanprintitsbirthdaygreeting.

Here’sanexamplethatcombinestheNamedprotocolfromthepreviousexamplewithaLocationclass:

1 classLocation{

2 varlatitude:Double

3 varlongitude:Double

4 init(latitude:Double,longitude:Double){

5 self.latitude=latitude

6 self.longitude=longitude

7 }

8 }

9 classCity:Location,Named{

10 varname:String

11 init(name:String,latitude:Double,longitude:Double){

12 self.name=name

13 super.init(latitude:latitude,longitude:longitude)

14 }

15 }

16 funcbeginConcert(inlocation:Location&Named){

17 print("Hello,\(location.name)!")

Page 408: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

18 }

19

20 letseattle=City(name:"Seattle",latitude:47.6,longitude:

-122.3)

21 beginConcert(in:seattle)

22 //Prints"Hello,Seattle!"

ThebeginConcert(in:)functiontakesaparameteroftypeLocation&Named,whichmeans“anytypethat’sasubclassofLocationandthatconformstotheNamedprotocol.”Inthiscase,Citysatisfiesbothrequirements.

PassingbirthdayPersontothebeginConcert(in:)functionisinvalidbecausePersonisn’tasubclassofLocation.Likewise,ifyoumadeasubclassofLocationthatdidn’tconformtotheNamedprotocol,callingbeginConcert(in:)withaninstanceofthattypeisalsoinvalid.

CheckingforProtocolConformance

YoucanusetheisandasoperatorsdescribedinTypeCastingtocheckforprotocolconformance,andtocasttoaspecificprotocol.Checkingforandcastingtoaprotocolfollowsexactlythesamesyntaxascheckingforandcastingtoatype:

Theisoperatorreturnstrueifaninstanceconformstoaprotocolandreturnsfalseifitdoesn’t.

Theas?versionofthedowncastoperatorreturnsanoptionalvalueoftheprotocol’stype,andthisvalueisniliftheinstancedoesn’tconformtothatprotocol.

Theas!versionofthedowncastoperatorforcesthedowncasttotheprotocoltypeandtriggersaruntimeerrorifthedowncastdoesn’tsucceed.

ThisexampledefinesaprotocolcalledHasArea,withasingleproperty

Page 409: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

requirementofagettableDoublepropertycalledarea:

1 protocolHasArea{

2 vararea:Double{get}

3 }

Herearetwoclasses,CircleandCountry,bothofwhichconformtotheHasAreaprotocol:

1 classCircle:HasArea{

2 letpi=3.1415927

3 varradius:Double

4 vararea:Double{returnpi*radius*radius}

5 init(radius:Double){self.radius=radius}

6 }

7 classCountry:HasArea{

8 vararea:Double

9 init(area:Double){self.area=area}

10 }

TheCircleclassimplementstheareapropertyrequirementasacomputedproperty,basedonastoredradiusproperty.TheCountryclassimplementsthearearequirementdirectlyasastoredproperty.BothclassescorrectlyconformtotheHasAreaprotocol.

Here’saclasscalledAnimal,whichdoesn’tconformtotheHasAreaprotocol:

1 classAnimal{

2 varlegs:Int

3 init(legs:Int){self.legs=legs}

4 }

TheCircle,CountryandAnimalclassesdon’thaveasharedbaseclass.

Page 410: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Nonetheless,they’reallclasses,andsoinstancesofallthreetypescanbeusedtoinitializeanarraythatstoresvaluesoftypeAnyObject:

1 letobjects:[AnyObject]=[

2 Circle(radius:2.0),

3 Country(area:243_610),

4 Animal(legs:4)

5 ]

TheobjectsarrayisinitializedwithanarrayliteralcontainingaCircleinstancewitharadiusof2units;aCountryinstanceinitializedwiththesurfaceareaoftheUnitedKingdominsquarekilometers;andanAnimalinstancewithfourlegs.

Theobjectsarraycannowbeiterated,andeachobjectinthearraycanbecheckedtoseeifitconformstotheHasAreaprotocol:

1 forobjectinobjects{

2 ifletobjectWithArea=objectas?HasArea{

3 print("Areais\(objectWithArea.area)")

4 }else{

5 print("Somethingthatdoesn'thaveanarea")

6 }

7 }

8 //Areais12.5663708

9 //Areais243610.0

10 //Somethingthatdoesn'thaveanarea

WheneveranobjectinthearrayconformstotheHasAreaprotocol,theoptionalvaluereturnedbytheas?operatorisunwrappedwithoptionalbindingintoaconstantcalledobjectWithArea.TheobjectWithAreaconstantisknowntobeoftypeHasArea,andsoitsareapropertycanbeaccessedandprintedinatype-safeway.

Notethattheunderlyingobjectsaren’tchangedbythecastingprocess.They

Page 411: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

continuetobeaCircle,aCountryandanAnimal.However,atthepointthatthey’restoredintheobjectWithAreaconstant,they’reonlyknowntobeoftypeHasArea,andsoonlytheirareapropertycanbeaccessed.

OptionalProtocolRequirements

Youcandefineoptionalrequirementsforprotocols.Theserequirementsdon’thavetobeimplementedbytypesthatconformtotheprotocol.Optionalrequirementsareprefixedbytheoptionalmodifieraspartoftheprotocol’sdefinition.OptionalrequirementsareavailablesothatyoucanwritecodethatinteroperateswithObjective-C.Boththeprotocolandtheoptionalrequirementmustbemarkedwiththe@objcattribute.Notethat@objcprotocolscanbeadoptedonlybyclassesthatinheritfromObjective-Cclassesorother@objcclasses.Theycan’tbeadoptedbystructuresorenumerations.

Whenyouuseamethodorpropertyinanoptionalrequirement,itstypeautomaticallybecomesanoptional.Forexample,amethodoftype(Int)->Stringbecomes((Int)->String)?.Notethattheentirefunctiontypeiswrappedintheoptional,notthemethod’sreturnvalue.

Anoptionalprotocolrequirementcanbecalledwithoptionalchaining,toaccountforthepossibilitythattherequirementwasnotimplementedbyatypethatconformstotheprotocol.Youcheckforanimplementationofanoptionalmethodbywritingaquestionmarkafterthenameofthemethodwhenit’scalled,suchassomeOptionalMethod?(someArgument).Forinformationonoptionalchaining,seeOptionalChaining.

Thefollowingexampledefinesaninteger-countingclasscalledCounter,whichusesanexternaldatasourcetoprovideitsincrementamount.ThisdatasourceisdefinedbytheCounterDataSourceprotocol,whichhastwooptionalrequirements:

1 @objcprotocolCounterDataSource{

2 @objcoptionalfuncincrement(forCountcount:Int)->Int

3 @objcoptionalvarfixedIncrement:Int{get}

Page 412: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 }

TheCounterDataSourceprotocoldefinesanoptionalmethodrequirementcalledincrement(forCount:)andanoptionalpropertyrequirementcalledfixedIncrement.TheserequirementsdefinetwodifferentwaysfordatasourcestoprovideanappropriateincrementamountforaCounterinstance.

NOTE

Strictlyspeaking,youcanwriteacustomclassthatconformstoCounterDataSourcewithoutimplementingeitherprotocolrequirement.They’rebothoptional,afterall.Althoughtechnicallyallowed,thiswouldn’tmakeforaverygooddatasource.

TheCounterclass,definedbelow,hasanoptionaldataSourcepropertyoftypeCounterDataSource?:

1 classCounter{

2 varcount=0

3 vardataSource:CounterDataSource?

4 funcincrement(){

5 ifletamount=dataSource?.increment?(forCount:count)

{

6 count+=amount

7 }elseifletamount=dataSource?.fixedIncrement{

8 count+=amount

9 }

10 }

11 }

TheCounterclassstoresitscurrentvalueinavariablepropertycalledcount.TheCounterclassalsodefinesamethodcalledincrement,whichincrementsthecountpropertyeverytimethemethodiscalled.

Theincrement()methodfirsttriestoretrieveanincrementamountbylookingforanimplementationoftheincrement(forCount:)methodonitsdatasource.

Page 413: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theincrement()methodusesoptionalchainingtotrytocallincrement(forCount:),andpassesthecurrentcountvalueasthemethod’ssingleargument.

Notethattwolevelsofoptionalchainingareatplayhere.First,it’spossiblethatdataSourcemaybenil,andsodataSourcehasaquestionmarkafteritsnametoindicatethatincrement(forCount:)shouldbecalledonlyifdataSourceisn’tnil.Second,evenifdataSourcedoesexist,there’snoguaranteethatitimplementsincrement(forCount:),becauseit’sanoptionalrequirement.Here,thepossibilitythatincrement(forCount:)mightnotbeimplementedisalsohandledbyoptionalchaining.Thecalltoincrement(forCount:)happensonlyifincrement(forCount:)exists—thatis,ifitisn’tnil.Thisiswhyincrement(forCount:)isalsowrittenwithaquestionmarkafteritsname.

Becausethecalltoincrement(forCount:)canfailforeitherofthesetworeasons,thecallreturnsanoptionalIntvalue.Thisistrueeventhoughincrement(forCount:)isdefinedasreturninganon-optionalIntvalueinthedefinitionofCounterDataSource.Eventhoughtherearetwooptionalchainingoperations,oneafteranother,theresultisstillwrappedinasingleoptional.Formoreinformationaboutusingmultipleoptionalchainingoperations,seeLinkingMultipleLevelsofChaining.

Aftercallingincrement(forCount:),theoptionalIntthatitreturnsisunwrappedintoaconstantcalledamount,usingoptionalbinding.IftheoptionalIntdoescontainavalue—thatis,ifthedelegateandmethodbothexist,andthemethodreturnedavalue—theunwrappedamountisaddedontothestoredcountproperty,andincrementationiscomplete.

Ifit’snotpossibletoretrieveavaluefromtheincrement(forCount:)method—eitherbecausedataSourceisnil,orbecausethedatasourcedoesn’timplementincrement(forCount:)—thentheincrement()methodtriestoretrieveavaluefromthedatasource’sfixedIncrementpropertyinstead.ThefixedIncrementpropertyisalsoanoptionalrequirement,soitsvalueisanoptionalIntvalue,eventhoughfixedIncrementisdefinedasanon-optionalIntpropertyaspartoftheCounterDataSourceprotocoldefinition.

Here’sasimpleCounterDataSourceimplementationwherethedatasourcereturnsaconstantvalueof3everytimeit’squeried.Itdoesthisbyimplementing

Page 414: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

theoptionalfixedIncrementpropertyrequirement:

1 classThreeSource:NSObject,CounterDataSource{

2 letfixedIncrement=3

3 }

YoucanuseaninstanceofThreeSourceasthedatasourceforanewCounterinstance:

1 varcounter=Counter()

2 counter.dataSource=ThreeSource()

3 for_in1...4{

4 counter.increment()

5 print(counter.count)

6 }

7 //3

8 //6

9 //9

10 //12

ThecodeabovecreatesanewCounterinstance;setsitsdatasourcetobeanewThreeSourceinstance;andcallsthecounter’sincrement()methodfourtimes.Asexpected,thecounter’scountpropertyincreasesbythreeeachtimeincrement()iscalled.

Here’samorecomplexdatasourcecalledTowardsZeroSource,whichmakesaCounterinstancecountupordowntowardszerofromitscurrentcountvalue:

1 classTowardsZeroSource:NSObject,CounterDataSource{

2 funcincrement(forCountcount:Int)->Int{

3 ifcount==0{

4 return0

5 }elseifcount<0{

Page 415: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 return1

7 }else{

8 return-1

9 }

10 }

11 }

TheTowardsZeroSourceclassimplementstheoptionalincrement(forCount:)methodfromtheCounterDataSourceprotocolandusesthecountargumentvaluetoworkoutwhichdirectiontocountin.Ifcountisalreadyzero,themethodreturns0toindicatethatnofurthercountingshouldtakeplace.

YoucanuseaninstanceofTowardsZeroSourcewiththeexistingCounterinstancetocountfrom-4tozero.Oncethecounterreacheszero,nomorecountingtakesplace:

1 counter.count=-4

2 counter.dataSource=TowardsZeroSource()

3 for_in1...5{

4 counter.increment()

5 print(counter.count)

6 }

7 //-3

8 //-2

9 //-1

10 //0

11 //0

ProtocolExtensions

Protocolscanbeextendedtoprovidemethod,initializer,subscript,and

Page 416: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

computedpropertyimplementationstoconformingtypes.Thisallowsyoutodefinebehavioronprotocolsthemselves,ratherthanineachtype’sindividualconformanceorinaglobalfunction.

Forexample,theRandomNumberGeneratorprotocolcanbeextendedtoprovidearandomBool()method,whichusestheresultoftherequiredrandom()methodtoreturnarandomBoolvalue:

1 extensionRandomNumberGenerator{

2 funcrandomBool()->Bool{

3 returnrandom()>0.5

4 }

5 }

Bycreatinganextensionontheprotocol,allconformingtypesautomaticallygainthismethodimplementationwithoutanyadditionalmodification.

1 letgenerator=LinearCongruentialGenerator()

2 print("Here'sarandomnumber:\(generator.random())")

3 //Prints"Here'sarandomnumber:0.3746499199817101"

4 print("Andhere'sarandomBoolean:\(generator.randomBool())")

5 //Prints"Andhere'sarandomBoolean:true"

Protocolextensionscanaddimplementationstoconformingtypesbutcan’tmakeaprotocolextendorinheritfromanotherprotocol.Protocolinheritanceisalwaysspecifiedintheprotocoldeclarationitself.

ProvidingDefaultImplementationsYoucanuseprotocolextensionstoprovideadefaultimplementationtoanymethodorcomputedpropertyrequirementofthatprotocol.Ifaconformingtypeprovidesitsownimplementationofarequiredmethodorproperty,thatimplementationwillbeusedinsteadoftheoneprovidedbytheextension.

Page 417: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Protocolrequirementswithdefaultimplementationsprovidedbyextensionsaredistinctfromoptionalprotocolrequirements.Althoughconformingtypesdon’thavetoprovidetheirownimplementationofeither,requirementswithdefaultimplementationscanbecalledwithoutoptionalchaining.

Forexample,thePrettyTextRepresentableprotocol,whichinheritstheTextRepresentableprotocolcanprovideadefaultimplementationofitsrequiredprettyTextualDescriptionpropertytosimplyreturntheresultofaccessingthetextualDescriptionproperty:

1 extensionPrettyTextRepresentable{

2 varprettyTextualDescription:String{

3 returntextualDescription

4 }

5 }

AddingConstraintstoProtocolExtensionsWhenyoudefineaprotocolextension,youcanspecifyconstraintsthatconformingtypesmustsatisfybeforethemethodsandpropertiesoftheextensionareavailable.Youwritetheseconstraintsafterthenameoftheprotocolyou’reextendingbywritingagenericwhereclause.Formoreaboutgenericwhereclauses,seeGenericWhereClauses.

Forexample,youcandefineanextensiontotheCollectionprotocolthatappliestoanycollectionwhoseelementsconformtotheEquatableprotocol.Byconstrainingacollection’selementstotheEquatableprotocol,apartofthestandardlibrary,youcanusethe==and!=operatorstocheckforequalityandinequalitybetweentwoelements.

1 extensionCollectionwhereElement:Equatable{

2 funcallEqual()->Bool{

3 forelementinself{

4 ifelement!=self.first{

Page 418: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 returnfalse

6 }

7 }

8 returntrue

9 }

10 }

TheallEqual()methodreturnstrueonlyifalltheelementsinthecollectionareequal.

Considertwoarraysofintegers,onewherealltheelementsarethesame,andonewheretheyaren’t:

1 letequalNumbers=[100,100,100,100,100]

2 letdifferentNumbers=[100,100,200,100,200]

BecausearraysconformtoCollectionandintegersconformtoEquatable,equalNumbersanddifferentNumberscanusetheallEqual()method:

1 print(equalNumbers.allEqual())

2 //Prints"true"

3 print(differentNumbers.allEqual())

4 //Prints"false"

NOTE

Ifaconformingtypesatisfiestherequirementsformultipleconstrainedextensionsthatprovideimplementationsforthesamemethodorproperty,Swiftusestheimplementationcorrespondingtothemostspecializedconstraints.

Page 419: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Generics

Genericcodeenablesyoutowriteflexible,reusablefunctionsandtypesthatcanworkwithanytype,subjecttorequirementsthatyoudefine.Youcanwritecodethatavoidsduplicationandexpressesitsintentinaclear,abstractedmanner.

GenericsareoneofthemostpowerfulfeaturesofSwift,andmuchoftheSwiftstandardlibraryisbuiltwithgenericcode.Infact,you’vebeenusinggenericsthroughouttheLanguageGuide,evenifyoudidn’trealizeit.Forexample,Swift’sArrayandDictionarytypesarebothgenericcollections.YoucancreateanarraythatholdsIntvalues,oranarraythatholdsStringvalues,orindeedanarrayforanyothertypethatcanbecreatedinSwift.Similarly,youcancreateadictionarytostorevaluesofanyspecifiedtype,andtherearenolimitationsonwhatthattypecanbe.

TheProblemThatGenericsSolve

Here’sastandard,nongenericfunctioncalledswapTwoInts(_:_:),whichswapstwoIntvalues:

1 funcswapTwoInts(_a:inoutInt,_b:inoutInt){

2 lettemporaryA=a

3 a=b

4 b=temporaryA

5 }

Thisfunctionmakesuseofin-outparameterstoswapthevaluesofaandb,asdescribedinIn-OutParameters.

TheswapTwoInts(_:_:)functionswapstheoriginalvalueofbintoa,andtheoriginalvalueofaintob.YoucancallthisfunctiontoswapthevaluesintwoIntvariables:

Page 420: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 varsomeInt=3

2 varanotherInt=107

3 swapTwoInts(&someInt,&anotherInt)

4 print("someIntisnow\(someInt),andanotherIntisnow\

(anotherInt)")

5 //Prints"someIntisnow107,andanotherIntisnow3"

TheswapTwoInts(_:_:)functionisuseful,butitcanonlybeusedwithIntvalues.IfyouwanttoswaptwoStringvalues,ortwoDoublevalues,youhavetowritemorefunctions,suchastheswapTwoStrings(_:_:)andswapTwoDoubles(_:_:)functionsshownbelow:

1 funcswapTwoStrings(_a:inoutString,_b:inoutString){

2 lettemporaryA=a

3 a=b

4 b=temporaryA

5 }

6

7 funcswapTwoDoubles(_a:inoutDouble,_b:inoutDouble){

8 lettemporaryA=a

9 a=b

10 b=temporaryA

11 }

YoumayhavenoticedthatthebodiesoftheswapTwoInts(_:_:),swapTwoStrings(_:_:),andswapTwoDoubles(_:_:)functionsareidentical.Theonlydifferenceisthetypeofthevaluesthattheyaccept(Int,String,andDouble).

It’smoreuseful,andconsiderablymoreflexible,towriteasinglefunctionthatswapstwovaluesofanytype.Genericcodeenablesyoutowritesuchafunction.(Agenericversionofthesefunctionsisdefinedbelow.)

Page 421: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

NOTE

Inallthreefunctions,thetypesofaandbmustbethesame.Ifaandbaren’tofthesametype,itisn’tpossibletoswaptheirvalues.Swiftisatype-safelanguage,anddoesn’tallow(forexample)avariableoftypeStringandavariableoftypeDoubletoswapvalueswitheachother.Attemptingtodosoresultsinacompile-timeerror.

GenericFunctions

Genericfunctionscanworkwithanytype.Here’sagenericversionoftheswapTwoInts(_:_:)functionfromabove,calledswapTwoValues(_:_:):

1 funcswapTwoValues<T>(_a:inoutT,_b:inoutT){

2 lettemporaryA=a

3 a=b

4 b=temporaryA

5 }

ThebodyoftheswapTwoValues(_:_:)functionisidenticaltothebodyoftheswapTwoInts(_:_:)function.However,thefirstlineofswapTwoValues(_:_:)isslightlydifferentfromswapTwoInts(_:_:).Here’showthefirstlinescompare:

1 funcswapTwoInts(_a:inoutInt,_b:inoutInt)

2 funcswapTwoValues<T>(_a:inoutT,_b:inoutT)

Thegenericversionofthefunctionusesaplaceholdertypename(calledT,inthiscase)insteadofanactualtypename(suchasInt,String,orDouble).Theplaceholdertypenamedoesn’tsayanythingaboutwhatTmustbe,butitdoessaythatbothaandbmustbeofthesametypeT,whateverTrepresents.TheactualtypetouseinplaceofTisdeterminedeachtimetheswapTwoValues(_:_:)functioniscalled.

Theotherdifferencebetweenagenericfunctionandanongenericfunctionisthatthegenericfunction’sname(swapTwoValues(_:_:))isfollowedbythe

Page 422: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

placeholdertypename(T)insideanglebrackets(<T>).ThebracketstellSwiftthatTisaplaceholdertypenamewithintheswapTwoValues(_:_:)functiondefinition.BecauseTisaplaceholder,Swiftdoesn’tlookforanactualtypecalledT.

TheswapTwoValues(_:_:)functioncannowbecalledinthesamewayasswapTwoInts,exceptthatitcanbepassedtwovaluesofanytype,aslongasbothofthosevaluesareofthesametypeaseachother.EachtimeswapTwoValues(_:_:)iscalled,thetypetouseforTisinferredfromthetypesofvaluespassedtothefunction.

Inthetwoexamplesbelow,TisinferredtobeIntandStringrespectively:

1 varsomeInt=3

2 varanotherInt=107

3 swapTwoValues(&someInt,&anotherInt)

4 //someIntisnow107,andanotherIntisnow3

5

6 varsomeString="hello"

7 varanotherString="world"

8 swapTwoValues(&someString,&anotherString)

9 //someStringisnow"world",andanotherStringisnow"hello"

NOTE

TheswapTwoValues(_:_:)functiondefinedaboveisinspiredbyagenericfunctioncalledswap,whichispartoftheSwiftstandardlibrary,andisautomaticallymadeavailableforyoutouseinyourapps.IfyouneedthebehavioroftheswapTwoValues(_:_:)functioninyourowncode,youcanuseSwift’sexistingswap(_:_:)functionratherthanprovidingyourownimplementation.

TypeParameters

IntheswapTwoValues(_:_:)exampleabove,theplaceholdertypeTisanexampleofatypeparameter.Typeparametersspecifyandnameaplaceholdertype,and

Page 423: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

arewrittenimmediatelyafterthefunction’sname,betweenapairofmatchinganglebrackets(suchas<T>).

Onceyouspecifyatypeparameter,youcanuseittodefinethetypeofafunction’sparameters(suchastheaandbparametersoftheswapTwoValues(_:_:)function),orasthefunction’sreturntype,orasatypeannotationwithinthebodyofthefunction.Ineachcase,thetypeparameterisreplacedwithanactualtypewheneverthefunctioniscalled.(IntheswapTwoValues(_:_:)exampleabove,TwasreplacedwithIntthefirsttimethefunctionwascalled,andwasreplacedwithStringthesecondtimeitwascalled.)

Youcanprovidemorethanonetypeparameterbywritingmultipletypeparameternameswithintheanglebrackets,separatedbycommas.

NamingTypeParameters

Inmostcases,typeparametershavedescriptivenames,suchasKeyandValueinDictionary<Key,Value>andElementinArray<Element>,whichtellsthereaderabouttherelationshipbetweenthetypeparameterandthegenerictypeorfunctionit’susedin.However,whenthereisn’tameaningfulrelationshipbetweenthem,it’straditionaltonamethemusingsingleletterssuchasT,U,andV,suchasTintheswapTwoValues(_:_:)functionabove.

NOTE

Alwaysgivetypeparametersuppercamelcasenames(suchasTandMyTypeParameter)toindicatethatthey’reaplaceholderforatype,notavalue.

GenericTypes

Inadditiontogenericfunctions,Swiftenablesyoutodefineyourowngenerictypes.Thesearecustomclasses,structures,andenumerationsthatcanworkwithanytype,inasimilarwaytoArrayandDictionary.

Page 424: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThissectionshowsyouhowtowriteagenericcollectiontypecalledStack.Astackisanorderedsetofvalues,similartoanarray,butwithamorerestrictedsetofoperationsthanSwift’sArraytype.Anarrayallowsnewitemstobeinsertedandremovedatanylocationinthearray.Astack,however,allowsnewitemstobeappendedonlytotheendofthecollection(knownaspushinganewvalueontothestack).Similarly,astackallowsitemstoberemovedonlyfromtheendofthecollection(knownaspoppingavalueoffthestack).

NOTE

TheconceptofastackisusedbytheUINavigationControllerclasstomodeltheviewcontrollersinitsnavigationhierarchy.YoucalltheUINavigationControllerclasspushViewController(_:animated:)methodtoadd(orpush)aviewcontrollerontothenavigationstack,anditspopViewControllerAnimated(_:)methodtoremove(orpop)aviewcontrollerfromthenavigationstack.Astackisausefulcollectionmodelwheneveryouneedastrict“lastin,firstout”approachtomanagingacollection.

Theillustrationbelowshowsthepushandpopbehaviorforastack:

1. Therearecurrentlythreevaluesonthestack.

2. Afourthvalueispushedontothetopofthestack.

3. Thestacknowholdsfourvalues,withthemostrecentoneatthetop.

4. Thetopiteminthestackispopped.

Page 425: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5. Afterpoppingavalue,thestackonceagainholdsthreevalues.

Here’showtowriteanongenericversionofastack,inthiscaseforastackofIntvalues:

1 structIntStack{

2 varitems=[Int]()

3 mutatingfuncpush(_item:Int){

4 items.append(item)

5 }

6 mutatingfuncpop()->Int{

7 returnitems.removeLast()

8 }

9 }

ThisstructureusesanArraypropertycalleditemstostorethevaluesinthestack.Stackprovidestwomethods,pushandpop,topushandpopvaluesonandoffthestack.Thesemethodsaremarkedasmutating,becausetheyneedtomodify(ormutate)thestructure’sitemsarray.

TheIntStacktypeshownabovecanonlybeusedwithIntvalues,however.ItwouldbemuchmoreusefultodefineagenericStackclass,thatcanmanageastackofanytypeofvalue.

Here’sagenericversionofthesamecode:

1 structStack<Element>{

2 varitems=[Element]()

3 mutatingfuncpush(_item:Element){

4 items.append(item)

5 }

6 mutatingfuncpop()->Element{

7 returnitems.removeLast()

Page 426: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 }

9 }

NotehowthegenericversionofStackisessentiallythesameasthenongenericversion,butwithatypeparametercalledElementinsteadofanactualtypeofInt.Thistypeparameteriswrittenwithinapairofanglebrackets(<Element>)immediatelyafterthestructure’sname.

Elementdefinesaplaceholdernameforatypetobeprovidedlater.ThisfuturetypecanbereferredtoasElementanywherewithinthestructure’sdefinition.Inthiscase,Elementisusedasaplaceholderinthreeplaces:

Tocreateapropertycalleditems,whichisinitializedwithanemptyarrayofvaluesoftypeElement

Tospecifythatthepush(_:)methodhasasingleparametercalleditem,whichmustbeoftypeElement

Tospecifythatthevaluereturnedbythepop()methodwillbeavalueoftypeElement

Becauseit’sagenerictype,StackcanbeusedtocreateastackofanyvalidtypeinSwift,inasimilarmannertoArrayandDictionary.

YoucreateanewStackinstancebywritingthetypetobestoredinthestackwithinanglebrackets.Forexample,tocreateanewstackofstrings,youwriteStack<String>():

1 varstackOfStrings=Stack<String>()

2 stackOfStrings.push("uno")

3 stackOfStrings.push("dos")

4 stackOfStrings.push("tres")

5 stackOfStrings.push("cuatro")

6 //thestacknowcontains4strings

Here’showstackOfStringslooksafterpushingthesefourvaluesontothestack:

Page 427: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Poppingavaluefromthestackremovesandreturnsthetopvalue,"cuatro":

1 letfromTheTop=stackOfStrings.pop()

2 //fromTheTopisequalto"cuatro",andthestacknowcontains

3strings

Here’showthestacklooksafterpoppingitstopvalue:

ExtendingaGenericType

Whenyouextendagenerictype,youdon’tprovideatypeparameterlistaspartoftheextension’sdefinition.Instead,thetypeparameterlistfromtheoriginaltypedefinitionisavailablewithinthebodyoftheextension,andtheoriginaltypeparameternamesareusedtorefertothetypeparametersfromtheoriginaldefinition.

Page 428: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThefollowingexampleextendsthegenericStacktypetoaddaread-onlycomputedpropertycalledtopItem,whichreturnsthetopitemonthestackwithoutpoppingitfromthestack:

1 extensionStack{

2 vartopItem:Element?{

3 returnitems.isEmpty?nil:items[items.count-1]

4 }

5 }

ThetopItempropertyreturnsanoptionalvalueoftypeElement.Ifthestackisempty,topItemreturnsnil;ifthestackisn’tempty,topItemreturnsthefinalitemintheitemsarray.

Notethatthisextensiondoesn’tdefineatypeparameterlist.Instead,theStacktype’sexistingtypeparametername,Element,isusedwithintheextensiontoindicatetheoptionaltypeofthetopItemcomputedproperty.

ThetopItemcomputedpropertycannowbeusedwithanyStackinstancetoaccessandqueryitstopitemwithoutremovingit.

1 iflettopItem=stackOfStrings.topItem{

2 print("Thetopitemonthestackis\(topItem).")

3 }

4 //Prints"Thetopitemonthestackistres."

Extensionsofagenerictypecanalsoincluderequirementsthatinstancesoftheextendedtypemustsatisfyinordertogainthenewfunctionality,asdiscussedinExtensionswithaGenericWhereClausebelow.

TypeConstraints

TheswapTwoValues(_:_:)functionandtheStacktypecanworkwithanytype.

Page 429: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

However,it’ssometimesusefultoenforcecertaintypeconstraintsonthetypesthatcanbeusedwithgenericfunctionsandgenerictypes.Typeconstraintsspecifythatatypeparametermustinheritfromaspecificclass,orconformtoaparticularprotocolorprotocolcomposition.

Forexample,Swift’sDictionarytypeplacesalimitationonthetypesthatcanbeusedaskeysforadictionary.AsdescribedinDictionaries,thetypeofadictionary’skeysmustbehashable.Thatis,itmustprovideawaytomakeitselfuniquelyrepresentable.Dictionaryneedsitskeystobehashablesothatitcancheckwhetheritalreadycontainsavalueforaparticularkey.Withoutthisrequirement,Dictionarycouldnottellwhetheritshouldinsertorreplaceavalueforaparticularkey,norwoulditbeabletofindavalueforagivenkeythatisalreadyinthedictionary.

ThisrequirementisenforcedbyatypeconstraintonthekeytypeforDictionary,whichspecifiesthatthekeytypemustconformtotheHashableprotocol,aspecialprotocoldefinedintheSwiftstandardlibrary.AllofSwift’sbasictypes(suchasString,Int,Double,andBool)arehashablebydefault.

Youcandefineyourowntypeconstraintswhencreatingcustomgenerictypes,andtheseconstraintsprovidemuchofthepowerofgenericprogramming.AbstractconceptslikeHashablecharacterizetypesintermsoftheirconceptualcharacteristics,ratherthantheirconcretetype.

TypeConstraintSyntaxYouwritetypeconstraintsbyplacingasingleclassorprotocolconstraintafteratypeparameter’sname,separatedbyacolon,aspartofthetypeparameterlist.Thebasicsyntaxfortypeconstraintsonagenericfunctionisshownbelow(althoughthesyntaxisthesameforgenerictypes):

1 funcsomeFunction<T:SomeClass,U:SomeProtocol>(someT:T,

someU:U){

2 //functionbodygoeshere

3 }

Page 430: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thehypotheticalfunctionabovehastwotypeparameters.Thefirsttypeparameter,T,hasatypeconstraintthatrequiresTtobeasubclassofSomeClass.Thesecondtypeparameter,U,hasatypeconstraintthatrequiresUtoconformtotheprotocolSomeProtocol.

TypeConstraintsinActionHere’sanongenericfunctioncalledfindIndex(ofString:in:),whichisgivenaStringvaluetofindandanarrayofStringvalueswithinwhichtofindit.ThefindIndex(ofString:in:)functionreturnsanoptionalIntvalue,whichwillbetheindexofthefirstmatchingstringinthearrayifit’sfound,ornilifthestringcan’tbefound:

1 funcfindIndex(ofStringvalueToFind:String,inarray:

[String])->Int?{

2 for(index,value)inarray.enumerated(){

3 ifvalue==valueToFind{

4 returnindex

5 }

6 }

7 returnnil

8 }

ThefindIndex(ofString:in:)functioncanbeusedtofindastringvalueinanarrayofstrings:

1 letstrings=["cat","dog","llama","parakeet","terrapin"]

2 ifletfoundIndex=findIndex(ofString:"llama",in:strings){

3 print("Theindexofllamais\(foundIndex)")

4 }

5 //Prints"Theindexofllamais2"

Theprincipleoffindingtheindexofavalueinanarrayisn’tusefulonlyfor

Page 431: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

strings,however.YoucanwritethesamefunctionalityasagenericfunctionbyreplacinganymentionofstringswithvaluesofsometypeTinstead.

Here’showyoumightexpectagenericversionoffindIndex(ofString:in:),calledfindIndex(of:in:),tobewritten.NotethatthereturntypeofthisfunctionisstillInt?,becausethefunctionreturnsanoptionalindexnumber,notanoptionalvaluefromthearray.Bewarned,though—thisfunctiondoesn’tcompile,forreasonsexplainedaftertheexample:

1 funcfindIndex<T>(ofvalueToFind:T,inarray:[T])->Int?{

2 for(index,value)inarray.enumerated(){

3 ifvalue==valueToFind{

4 returnindex

5 }

6 }

7 returnnil

8 }

Thisfunctiondoesn’tcompileaswrittenabove.Theproblemlieswiththeequalitycheck,“ifvalue==valueToFind”.NoteverytypeinSwiftcanbecomparedwiththeequaltooperator(==).Ifyoucreateyourownclassorstructuretorepresentacomplexdatamodel,forexample,thenthemeaningof“equalto”forthatclassorstructureisn’tsomethingthatSwiftcanguessforyou.Becauseofthis,itisn’tpossibletoguaranteethatthiscodewillworkforeverypossibletypeT,andanappropriateerrorisreportedwhenyoutrytocompilethecode.

Allisnotlost,however.TheSwiftstandardlibrarydefinesaprotocolcalledEquatable,whichrequiresanyconformingtypetoimplementtheequaltooperator(==)andthenotequaltooperator(!=)tocompareanytwovaluesofthattype.AllofSwift’sstandardtypesautomaticallysupporttheEquatableprotocol.

AnytypethatisEquatablecanbeusedsafelywiththefindIndex(of:in:)function,becauseit’sguaranteedtosupporttheequaltooperator.Toexpressthisfact,youwriteatypeconstraintofEquatableaspartofthetypeparameter’sdefinitionwhenyoudefinethefunction:

Page 432: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 funcfindIndex<T:Equatable>(ofvalueToFind:T,inarray:[T])-

>Int?{

2 for(index,value)inarray.enumerated(){

3 ifvalue==valueToFind{

4 returnindex

5 }

6 }

7 returnnil

8 }

ThesingletypeparameterforfindIndex(of:in:)iswrittenasT:Equatable,whichmeans“anytypeTthatconformstotheEquatableprotocol.”

ThefindIndex(of:in:)functionnowcompilessuccessfullyandcanbeusedwithanytypethatisEquatable,suchasDoubleorString:

1 letdoubleIndex=findIndex(of:9.3,in:[3.14159,0.1,0.25])

2 //doubleIndexisanoptionalIntwithnovalue,because9.3

isn'tinthearray

3 letstringIndex=findIndex(of:"Andrea",in:["Mike",

"Malcolm","Andrea"])

4 //stringIndexisanoptionalIntcontainingavalueof2

AssociatedTypes

Whendefiningaprotocol,it’ssometimesusefultodeclareoneormoreassociatedtypesaspartoftheprotocol’sdefinition.Anassociatedtypegivesaplaceholdernametoatypethatisusedaspartoftheprotocol.Theactualtypetouseforthatassociatedtypeisn’tspecifieduntiltheprotocolisadopted.Associatedtypesarespecifiedwiththeassociatedtypekeyword.

Page 433: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AssociatedTypesinActionHere’sanexampleofaprotocolcalledContainer,whichdeclaresanassociatedtypecalledItem:

1 protocolContainer{

2 associatedtypeItem

3 mutatingfuncappend(_item:Item)

4 varcount:Int{get}

5 subscript(i:Int)->Item{get}

6 }

TheContainerprotocoldefinesthreerequiredcapabilitiesthatanycontainermustprovide:

Itmustbepossibletoaddanewitemtothecontainerwithanappend(_:)method.

ItmustbepossibletoaccessacountoftheitemsinthecontainerthroughacountpropertythatreturnsanIntvalue.

ItmustbepossibletoretrieveeachiteminthecontainerwithasubscriptthattakesanIntindexvalue.

Thisprotocoldoesn’tspecifyhowtheitemsinthecontainershouldbestoredorwhattypethey’reallowedtobe.TheprotocolonlyspecifiesthethreebitsoffunctionalitythatanytypemustprovideinordertobeconsideredaContainer.Aconformingtypecanprovideadditionalfunctionality,aslongasitsatisfiesthesethreerequirements.

AnytypethatconformstotheContainerprotocolmustbeabletospecifythetypeofvaluesitstores.Specifically,itmustensurethatonlyitemsoftherighttypeareaddedtothecontainer,anditmustbeclearaboutthetypeoftheitemsreturnedbyitssubscript.

Todefinetheserequirements,theContainerprotocolneedsawaytorefertothetypeoftheelementsthatacontainerwillhold,withoutknowingwhatthattypeis

Page 434: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

foraspecificcontainer.TheContainerprotocolneedstospecifythatanyvaluepassedtotheappend(_:)methodmusthavethesametypeasthecontainer’selementtype,andthatthevaluereturnedbythecontainer’ssubscriptwillbeofthesametypeasthecontainer’selementtype.

Toachievethis,theContainerprotocoldeclaresanassociatedtypecalledItem,writtenasassociatedtypeItem.Theprotocoldoesn’tdefinewhatItemis—thatinformationisleftforanyconformingtypetoprovide.Nonetheless,theItemaliasprovidesawaytorefertothetypeoftheitemsinaContainer,andtodefineatypeforusewiththeappend(_:)methodandsubscript,toensurethattheexpectedbehaviorofanyContainerisenforced.

Here’saversionofthenongenericIntStacktypefromGenericTypesabove,adaptedtoconformtotheContainerprotocol:

1 structIntStack:Container{

2 //originalIntStackimplementation

3 varitems=[Int]()

4 mutatingfuncpush(_item:Int){

5 items.append(item)

6 }

7 mutatingfuncpop()->Int{

8 returnitems.removeLast()

9 }

10 //conformancetotheContainerprotocol

11 typealiasItem=Int

12 mutatingfuncappend(_item:Int){

13 self.push(item)

14 }

15 varcount:Int{

16 returnitems.count

17 }

18 subscript(i:Int)->Int{

Page 435: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

19 returnitems[i]

20 }

21 }

TheIntStacktypeimplementsallthreeoftheContainerprotocol’srequirements,andineachcasewrapspartoftheIntStacktype’sexistingfunctionalitytosatisfytheserequirements.

Moreover,IntStackspecifiesthatforthisimplementationofContainer,theappropriateItemtouseisatypeofInt.ThedefinitionoftypealiasItem=IntturnstheabstracttypeofItemintoaconcretetypeofIntforthisimplementationoftheContainerprotocol.

ThankstoSwift’stypeinference,youdon’tactuallyneedtodeclareaconcreteItemofIntaspartofthedefinitionofIntStack.BecauseIntStackconformstoalloftherequirementsoftheContainerprotocol,SwiftcaninfertheappropriateItemtouse,simplybylookingatthetypeoftheappend(_:)method’sitemparameterandthereturntypeofthesubscript.Indeed,ifyoudeletethetypealiasItem=Intlinefromthecodeabove,everythingstillworks,becauseit’sclearwhattypeshouldbeusedforItem.

YoucanalsomakethegenericStacktypeconformtotheContainerprotocol:

1 structStack<Element>:Container{

2 //originalStack<Element>implementation

3 varitems=[Element]()

4 mutatingfuncpush(_item:Element){

5 items.append(item)

6 }

7 mutatingfuncpop()->Element{

8 returnitems.removeLast()

9 }

10 //conformancetotheContainerprotocol

11 mutatingfuncappend(_item:Element){

Page 436: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

12 self.push(item)

13 }

14 varcount:Int{

15 returnitems.count

16 }

17 subscript(i:Int)->Element{

18 returnitems[i]

19 }

20 }

Thistime,thetypeparameterElementisusedasthetypeoftheappend(_:)method’sitemparameterandthereturntypeofthesubscript.SwiftcanthereforeinferthatElementistheappropriatetypetouseastheItemforthisparticularcontainer.

ExtendinganExistingTypetoSpecifyanAssociatedTypeYoucanextendanexistingtypetoaddconformancetoaprotocol,asdescribedinAddingProtocolConformancewithanExtension.Thisincludesaprotocolwithanassociatedtype.

Swift’sArraytypealreadyprovidesanappend(_:)method,acountproperty,andasubscriptwithanIntindextoretrieveitselements.ThesethreecapabilitiesmatchtherequirementsoftheContainerprotocol.ThismeansthatyoucanextendArraytoconformtotheContainerprotocolsimplybydeclaringthatArrayadoptstheprotocol.Youdothiswithanemptyextension,asdescribedinDeclaringProtocolAdoptionwithanExtension:

extensionArray:Container{}

Array’sexistingappend(_:)methodandsubscriptenableSwifttoinfertheappropriatetypetouseforItem,justasforthegenericStacktypeabove.Afterdefiningthisextension,youcanuseanyArrayasaContainer.

Page 437: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddingConstraintstoanAssociatedTypeYoucanaddtypeconstraintstoanassociatedtypeinaprotocoltorequirethatconformingtypessatisfythoseconstraints.Forexample,thefollowingcodedefinesaversionofContainerthatrequirestheitemsinthecontainertobeequatable.

1 protocolContainer{

2 associatedtypeItem:Equatable

3 mutatingfuncappend(_item:Item)

4 varcount:Int{get}

5 subscript(i:Int)->Item{get}

6 }

ToconformtothisversionofContainer,thecontainer’sItemtypehastoconformtotheEquatableprotocol.

UsingaProtocolinItsAssociatedType’sConstraintsAprotocolcanappearaspartofitsownrequirements.Forexample,here’saprotocolthatrefinestheContainerprotocol,addingtherequirementofasuffix(_:)method.Thesuffix(_:)methodreturnsagivennumberofelementsfromtheendofthecontainer,storingtheminaninstanceoftheSuffixtype.

1 protocolSuffixableContainer:Container{

2 associatedtypeSuffix:SuffixableContainerwhere

Suffix.Item==Item

3 funcsuffix(_size:Int)->Suffix

4 }

Inthisprotocol,Suffixisanassociatedtype,liketheItemtypeintheContainerexampleabove.Suffixhastwoconstraints:ItmustconformtotheSuffixableContainerprotocol(theprotocolcurrentlybeingdefined),anditsItemtypemustbethesameasthecontainer’sItemtype.TheconstraintonItem

Page 438: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

isagenericwhereclause,whichisdiscussedinAssociatedTypeswithaGenericWhereClausebelow.

Here’sanextensionoftheStacktypefromGenericTypesabovethataddsconformancetotheSuffixableContainerprotocol:

1 extensionStack:SuffixableContainer{

2 funcsuffix(_size:Int)->Stack{

3 varresult=Stack()

4 forindexin(count-size)..<count{

5 result.append(self[index])

6 }

7 returnresult

8 }

9 //InferredthatSuffixisStack.

10 }

11 varstackOfInts=Stack<Int>()

12 stackOfInts.append(10)

13 stackOfInts.append(20)

14 stackOfInts.append(30)

15 letsuffix=stackOfInts.suffix(2)

16 //suffixcontains20and30

Intheexampleabove,theSuffixassociatedtypeforStackisalsoStack,sothesuffixoperationonStackreturnsanotherStack.Alternatively,atypethatconformstoSuffixableContainercanhaveaSuffixtypethat’sdifferentfromitself—meaningthesuffixoperationcanreturnadifferenttype.Forexample,here’sanextensiontothenongenericIntStacktypethataddsSuffixableContainerconformance,usingStack<Int>asitssuffixtypeinsteadofIntStack:

1 extensionIntStack:SuffixableContainer{

2 funcsuffix(_size:Int)->Stack<Int>{

Page 439: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 varresult=Stack<Int>()

4 forindexin(count-size)..<count{

5 result.append(self[index])

6 }

7 returnresult

8 }

9 //InferredthatSuffixisStack<Int>.

10 }

GenericWhereClauses

Typeconstraints,asdescribedinTypeConstraints,enableyoutodefinerequirementsonthetypeparametersassociatedwithagenericfunction,subscript,ortype.

Itcanalsobeusefultodefinerequirementsforassociatedtypes.Youdothisbydefiningagenericwhereclause.Agenericwhereclauseenablesyoutorequirethatanassociatedtypemustconformtoacertainprotocol,orthatcertaintypeparametersandassociatedtypesmustbethesame.Agenericwhereclausestartswiththewherekeyword,followedbyconstraintsforassociatedtypesorequalityrelationshipsbetweentypesandassociatedtypes.Youwriteagenericwhereclauserightbeforetheopeningcurlybraceofatypeorfunction’sbody.

TheexamplebelowdefinesagenericfunctioncalledallItemsMatch,whichcheckstoseeiftwoContainerinstancescontainthesameitemsinthesameorder.ThefunctionreturnsaBooleanvalueoftrueifallitemsmatchandavalueoffalseiftheydon’t.

Thetwocontainerstobecheckeddon’thavetobethesametypeofcontainer(althoughtheycanbe),buttheydohavetoholdthesametypeofitems.Thisrequirementisexpressedthroughacombinationoftypeconstraintsandagenericwhereclause:

Page 440: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 funcallItemsMatch<C1:Container,C2:Container>

2 (_someContainer:C1,_anotherContainer:C2)->Bool

3 whereC1.Item==C2.Item,C1.Item:Equatable{

4

5 //Checkthatbothcontainerscontainthesamenumber

ofitems.

6 ifsomeContainer.count!=anotherContainer.count{

7 returnfalse

8 }

9

10 //Checkeachpairofitemstoseeifthey're

equivalent.

11 foriin0..<someContainer.count{

12 ifsomeContainer[i]!=anotherContainer[i]{

13 returnfalse

14 }

15 }

16

17 //Allitemsmatch,soreturntrue.

18 returntrue

19 }

ThisfunctiontakestwoargumentscalledsomeContainerandanotherContainer.ThesomeContainerargumentisoftypeC1,andtheanotherContainerargumentisoftypeC2.BothC1andC2aretypeparametersfortwocontainertypestobedeterminedwhenthefunctioniscalled.

Thefollowingrequirementsareplacedonthefunction’stwotypeparameters:

C1mustconformtotheContainerprotocol(writtenasC1:Container).

C2mustalsoconformtotheContainerprotocol(writtenasC2:Container).

Page 441: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheItemforC1mustbethesameastheItemforC2(writtenasC1.Item==C2.Item).

TheItemforC1mustconformtotheEquatableprotocol(writtenasC1.Item:Equatable).

Thefirstandsecondrequirementsaredefinedinthefunction’stypeparameterlist,andthethirdandfourthrequirementsaredefinedinthefunction’sgenericwhereclause.

Theserequirementsmean:

someContainerisacontaineroftypeC1.

anotherContainerisacontaineroftypeC2.

someContainerandanotherContainercontainthesametypeofitems.

TheitemsinsomeContainercanbecheckedwiththenotequaloperator(!=)toseeifthey’redifferentfromeachother.

ThethirdandfourthrequirementscombinetomeanthattheitemsinanotherContainercanalsobecheckedwiththe!=operator,becausethey’reexactlythesametypeastheitemsinsomeContainer.

TheserequirementsenabletheallItemsMatch(_:_:)functiontocomparethetwocontainers,evenifthey’reofadifferentcontainertype.

TheallItemsMatch(_:_:)functionstartsbycheckingthatbothcontainerscontainthesamenumberofitems.Iftheycontainadifferentnumberofitems,there’snowaythattheycanmatch,andthefunctionreturnsfalse.

Aftermakingthischeck,thefunctioniteratesoveralloftheitemsinsomeContainerwithafor-inloopandthehalf-openrangeoperator(..<).Foreachitem,thefunctioncheckswhethertheitemfromsomeContainerisn’tequaltothecorrespondingiteminanotherContainer.Ifthetwoitemsaren’tequal,thenthetwocontainersdon’tmatch,andthefunctionreturnsfalse.

Iftheloopfinisheswithoutfindingamismatch,thetwocontainersmatch,and

Page 442: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thefunctionreturnstrue.

Here’showtheallItemsMatch(_:_:)functionlooksinaction:

1 varstackOfStrings=Stack<String>()

2 stackOfStrings.push("uno")

3 stackOfStrings.push("dos")

4 stackOfStrings.push("tres")

5

6 vararrayOfStrings=["uno","dos","tres"]

7

8 ifallItemsMatch(stackOfStrings,arrayOfStrings){

9 print("Allitemsmatch.")

10 }else{

11 print("Notallitemsmatch.")

12 }

13 //Prints"Allitemsmatch."

TheexampleabovecreatesaStackinstancetostoreStringvalues,andpushesthreestringsontothestack.TheexamplealsocreatesanArrayinstanceinitializedwithanarrayliteralcontainingthesamethreestringsasthestack.Eventhoughthestackandthearrayareofadifferenttype,theybothconformtotheContainerprotocol,andbothcontainthesametypeofvalues.YoucanthereforecalltheallItemsMatch(_:_:)functionwiththesetwocontainersasitsarguments.Intheexampleabove,theallItemsMatch(_:_:)functioncorrectlyreportsthatalloftheitemsinthetwocontainersmatch.

ExtensionswithaGenericWhereClause

Youcanalsouseagenericwhereclauseaspartofanextension.TheexamplebelowextendsthegenericStackstructurefromthepreviousexamplestoaddanisTop(_:)method.

Page 443: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 extensionStackwhereElement:Equatable{

2 funcisTop(_item:Element)->Bool{

3 guardlettopItem=items.lastelse{

4 returnfalse

5 }

6 returntopItem==item

7 }

8 }

ThisnewisTop(_:)methodfirstchecksthatthestackisn’tempty,andthencomparesthegivenitemagainstthestack’stopmostitem.Ifyoutriedtodothiswithoutagenericwhereclause,youwouldhaveaproblem:TheimplementationofisTop(_:)usesthe==operator,butthedefinitionofStackdoesn’trequireitsitemstobeequatable,sousingthe==operatorresultsinacompile-timeerror.Usingagenericwhereclauseletsyouaddanewrequirementtotheextension,sothattheextensionaddstheisTop(_:)methodonlywhentheitemsinthestackareequatable.

Here’showtheisTop(_:)methodlooksinaction:

1 ifstackOfStrings.isTop("tres"){

2 print("Topelementistres.")

3 }else{

4 print("Topelementissomethingelse.")

5 }

6 //Prints"Topelementistres."

IfyoutrytocalltheisTop(_:)methodonastackwhoseelementsaren’tequatable,you’llgetacompile-timeerror.

1 structNotEquatable{}

2 varnotEquatableStack=Stack<NotEquatable>()

3 letnotEquatableValue=NotEquatable()

Page 444: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 notEquatableStack.push(notEquatableValue)

5 notEquatableStack.isTop(notEquatableValue)//Error

Youcanuseagenericwhereclausewithextensionstoaprotocol.TheexamplebelowextendstheContainerprotocolfromthepreviousexamplestoaddastartsWith(_:)method.

1 extensionContainerwhereItem:Equatable{

2 funcstartsWith(_item:Item)->Bool{

3 returncount>=1&&self[0]==item

4 }

5 }

ThestartsWith(_:)methodfirstmakessurethatthecontainerhasatleastoneitem,andthenitcheckswhetherthefirstiteminthecontainermatchesthegivenitem.ThisnewstartsWith(_:)methodcanbeusedwithanytypethatconformstotheContainerprotocol,includingthestacksandarraysusedabove,aslongasthecontainer’sitemsareequatable.

1 if[9,9,9].startsWith(42){

2 print("Startswith42.")

3 }else{

4 print("Startswithsomethingelse.")

5 }

6 //Prints"Startswithsomethingelse."

ThegenericwhereclauseintheexampleaboverequiresItemtoconformtoaprotocol,butyoucanalsowriteagenericwhereclausesthatrequireItemtobeaspecifictype.Forexample:

1 extensionContainerwhereItem==Double{

2 funcaverage()->Double{

3 varsum=0.0

Page 445: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 forindexin0..<count{

5 sum+=self[index]

6 }

7 returnsum/Double(count)

8 }

9 }

10 print([1260.0,1200.0,98.6,37.0].average())

11 //Prints"648.9"

Thisexampleaddsanaverage()methodtocontainerswhoseItemtypeisDouble.Ititeratesovertheitemsinthecontainertoaddthemup,anddividesbythecontainer’scounttocomputetheaverage.ItexplicitlyconvertsthecountfromInttoDoubletobeabletodofloating-pointdivision.

Youcanincludemultiplerequirementsinagenericwhereclausethatispartofanextension,justlikeyoucanforagenericwhereclausethatyouwriteelsewhere.Separateeachrequirementinthelistwithacomma.

AssociatedTypeswithaGenericWhereClause

Youcanincludeagenericwhereclauseonanassociatedtype.Forexample,supposeyouwanttomakeaversionofContainerthatincludesaniterator,likewhattheSequenceprotocolusesinthestandardlibrary.Here’showyouwritethat:

1 protocolContainer{

2 associatedtypeItem

3 mutatingfuncappend(_item:Item)

4 varcount:Int{get}

5 subscript(i:Int)->Item{get}

6

Page 446: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

7 associatedtypeIterator:IteratorProtocolwhere

Iterator.Element==Item

8 funcmakeIterator()->Iterator

9 }

ThegenericwhereclauseonIteratorrequiresthattheiteratormusttraverseoverelementsofthesameitemtypeasthecontainer’sitems,regardlessoftheiterator’stype.ThemakeIterator()functionprovidesaccesstoacontainer’siterator.

Foraprotocolthatinheritsfromanotherprotocol,youaddaconstrainttoaninheritedassociatedtypebyincludingthegenericwhereclauseintheprotocoldeclaration.Forexample,thefollowingcodedeclaresaComparableContainerprotocolthatrequiresItemtoconformtoComparable:

protocolComparableContainer:ContainerwhereItem:Comparable

{}

GenericSubscripts

Subscriptscanbegeneric,andtheycanincludegenericwhereclauses.Youwritetheplaceholdertypenameinsideanglebracketsaftersubscript,andyouwriteagenericwhereclauserightbeforetheopeningcurlybraceofthesubscript’sbody.Forexample:

1 extensionContainer{

2 subscript<Indices:Sequence>(indices:Indices)->[Item]

3 whereIndices.Iterator.Element==Int{

4 varresult=[Item]()

5 forindexinindices{

6 result.append(self[index])

7 }

Page 447: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 returnresult

9 }

10 }

ThisextensiontotheContainerprotocoladdsasubscriptthattakesasequenceofindicesandreturnsanarraycontainingtheitemsateachgivenindex.Thisgenericsubscriptisconstrainedasfollows:

ThegenericparameterIndicesinanglebracketshastobeatypethatconformstotheSequenceprotocolfromthestandardlibrary.

Thesubscripttakesasingleparameter,indices,whichisaninstanceofthatIndicestype.

ThegenericwhereclauserequiresthattheiteratorforthesequencemusttraverseoverelementsoftypeInt.Thisensuresthattheindicesinthesequencearethesametypeastheindicesusedforacontainer.

Takentogether,theseconstraintsmeanthatthevaluepassedfortheindicesparameterisasequenceofintegers.

Page 448: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

OpaqueTypes

Afunctionormethodwithanopaquereturntypehidesitsreturnvalue’stypeinformation.Insteadofprovidingaconcretetypeasthefunction’sreturntype,thereturnvalueisdescribedintermsoftheprotocolsitsupports.Hidingtypeinformationisusefulatboundariesbetweenamoduleandcodethatcallsintothemodule,becausetheunderlyingtypeofthereturnvaluecanremainprivate.Unlikereturningavaluewhosetypeisaprotocoltype,opaquetypespreservetypeidentity—thecompilerhasaccesstothetypeinformation,butclientsofthemoduledon’t.

TheProblemThatOpaqueTypesSolve

Forexample,supposeyou’rewritingamodulethatdrawsASCIIartshapes.ThebasiccharacteristicofanASCIIartshapeisadraw()functionthatreturnsthestringrepresentationofthatshape,whichyoucanuseastherequirementfortheShapeprotocol:

1 protocolShape{

2 funcdraw()->String

3 }

4

5 structTriangle:Shape{

6 varsize:Int

7 funcdraw()->String{

8 varresult=[String]()

9 forlengthin1...size{

10 result.append(String(repeating:"*",count:

length))

11 }

Page 449: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

12 returnresult.joined(separator:"\n")

13 }

14 }

15 letsmallTriangle=Triangle(size:3)

16 print(smallTriangle.draw())

17 //*

18 //**

19 //***

Youcouldusegenericstoimplementoperationslikeflippingashapevertically,asshowninthecodebelow.However,there’sanimportantlimitationtothisapproach:Theflippedresultexposestheexactgenerictypesthatwereusedtocreateit.

1 structFlippedShape<T:Shape>:Shape{

2 varshape:T

3 funcdraw()->String{

4 letlines=shape.draw().split(separator:"\n")

5 returnlines.reversed().joined(separator:"\n")

6 }

7 }

8 letflippedTriangle=FlippedShape(shape:smallTriangle)

9 print(flippedTriangle.draw())

10 //***

11 //**

12 //*

ThisapproachtodefiningaJoinedShape<T:Shape,U:Shape>structurethatjoinstwoshapestogethervertically,likethecodebelowshows,resultsintypeslikeJoinedShape<FlippedShape<Triangle>,Triangle>fromjoiningaflippedtrianglewithanothertriangle.

Page 450: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 structJoinedShape<T:Shape,U:Shape>:Shape{

2 vartop:T

3 varbottom:U

4 funcdraw()->String{

5 returntop.draw()+"\n"+bottom.draw()

6 }

7 }

8 letjoinedTriangles=JoinedShape(top:smallTriangle,bottom:

flippedTriangle)

9 print(joinedTriangles.draw())

10 //*

11 //**

12 //***

13 //***

14 //**

15 //*

Exposingdetailedinformationaboutthecreationofashapeallowstypesthataren’tmeanttobepartoftheASCIIartmodule’spublicinterfacetoleakoutbecauseoftheneedtostatethefullreturntype.Thecodeinsidethemodulecouldbuildupthesameshapeinavarietyofways,andothercodeoutsidethemodulethatusestheshapeshouldn’thavetoaccountfortheimplementationdetailsaboutthelistoftransformations.WrappertypeslikeJoinedShapeandFlippedShapedon’tmattertothemodule’susers,andtheyshouldn’tbevisible.Themodule’spublicinterfaceconsistsofoperationslikejoiningandflippingashape,andthoseoperationsreturnanotherShapevalue.

ReturninganOpaqueType

Youcanthinkofanopaquetypelikebeingthereverseofagenerictype.Generictypesletthecodethatcallsafunctionpickthetypeforthatfunction’s

Page 451: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

parametersandreturnvalueinawaythat’sabstractedawayfromthefunctionimplementation.Forexample,thefunctioninthefollowingcodereturnsatypethatdependsonitscaller:

funcmax<T>(_x:T,_y:T)->TwhereT:Comparable{...}

Thecodethatcallsmax(_:_:)choosesthevaluesforxandy,andthetypeofthosevaluesdeterminestheconcretetypeofT.ThecallingcodecanuseanytypethatconformstotheComparableprotocol.Thecodeinsidethefunctioniswritteninageneralwaysoitcanhandlewhatevertypethecallerprovides.Theimplementationofmax(_:_:)usesonlyfunctionalitythatallComparabletypesshare.

Thoserolesarereversedforafunctionwithanopaquereturntype.Anopaquetypeletsthefunctionimplementationpickthetypeforthevalueitreturnsinawaythat’sabstractedawayfromthecodethatcallsthefunction.Forexample,thefunctioninthefollowingexamplereturnsatrapezoidwithoutexposingtheunderlyingtypeofthatshape.

1 structSquare:Shape{

2 varsize:Int

3 funcdraw()->String{

4 letline=String(repeating:"*",count:size)

5 letresult=Array<String>(repeating:line,count:

size)

6 returnresult.joined(separator:"\n")

7 }

8 }

9

10 funcmakeTrapezoid()->someShape{

11 lettop=Triangle(size:2)

12 letmiddle=Square(size:2)

13 letbottom=FlippedShape(shape:top)

Page 452: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

14 lettrapezoid=JoinedShape(

15 top:top,

16 bottom:JoinedShape(top:middle,bottom:bottom)

17 )

18 returntrapezoid

19 }

20 lettrapezoid=makeTrapezoid()

21 print(trapezoid.draw())

22 //*

23 //**

24 //**

25 //**

26 //**

27 //*

ThemakeTrapezoid()functioninthisexampledeclaresitsreturntypeassomeShape;asaresult,thefunctionreturnsavalueofsomegiventypethatconformstotheShapeprotocol,withoutspecifyinganyparticularconcretetype.WritingmakeTrapezoid()thiswayletsitexpressthefundamentalaspectofitspublicinterface—thevalueitreturnsisashape—withoutmakingthespecifictypesthattheshapeismadefromapartofitspublicinterface.Thisimplementationusestwotrianglesandasquare,butthefunctioncouldberewrittentodrawatrapezoidinavarietyofotherwayswithoutchangingitsreturntype.

Thisexamplehighlightsthewaythatanopaquereturntypeislikethereverseofagenerictype.ThecodeinsidemakeTrapezoid()canreturnanytypeitneedsto,aslongasthattypeconformstotheShapeprotocol,likethecallingcodedoesforagenericfunction.Thecodethatcallsthefunctionneedstobewritteninageneralway,liketheimplementationofagenericfunction,sothatitcanworkwithanyShapevaluethat’sreturnedbymakeTrapezoid().

Youcanalsocombineopaquereturntypeswithgenerics.ThefunctionsinthefollowingcodebothreturnavalueofsometypethatconformstotheShapeprotocol.

Page 453: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 funcflip<T:Shape>(_shape:T)->someShape{

2 returnFlippedShape(shape:shape)

3 }

4 funcjoin<T:Shape,U:Shape>(_top:T,_bottom:U)->some

Shape{

5 JoinedShape(top:top,bottom:bottom)

6 }

7

8 letopaqueJoinedTriangles=join(smallTriangle,

flip(smallTriangle))

9 print(opaqueJoinedTriangles.draw())

10 //*

11 //**

12 //***

13 //***

14 //**

15 //*

ThevalueofopaqueJoinedTrianglesinthisexampleisthesameasjoinedTrianglesinthegenericsexampleintheTheProblemThatOpaqueTypesSolvesectionearlierinthischapter.However,unlikethevalueinthatexample,flip(_:)andjoin(_:_:)wraptheunderlyingtypesthatthegenericshapeoperationsreturninanopaquereturntype,whichpreventsthosetypesfrombeingvisible.Bothfunctionsaregenericbecausethetypestheyrelyonaregeneric,andthetypeparameterstothefunctionpassalongthetypeinformationneededbyFlippedShapeandJoinedShape.

Ifafunctionwithanopaquereturntypereturnsfrommultipleplaces,allofthepossiblereturnvaluesmusthavethesametype.Foragenericfunction,thatreturntypecanusethefunction’sgenerictypeparameters,butitmuststillbeasingletype.Forexample,here’saninvalidversionoftheshape-flippingfunctionthatincludesaspecialcaseforsquares:

Page 454: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 funcinvalidFlip<T:Shape>(_shape:T)->someShape{

2 ifshapeisSquare{

3 returnshape//Error:returntypesdon'tmatch

4 }

5 returnFlippedShape(shape:shape)//Error:returntypes

don'tmatch

6 }

IfyoucallthisfunctionwithaSquare,itreturnsaSquare;otherwise,itreturnsaFlippedShape.ThisviolatestherequirementtoreturnvaluesofonlyonetypeandmakesinvalidFlip(_:)invalidcode.OnewaytofixinvalidFlip(_:)istomovethespecialcaseforsquaresintotheimplementationofFlippedShape,whichletsthisfunctionalwaysreturnaFlippedShapevalue:

1 structFlippedShape<T:Shape>:Shape{

2 varshape:T

3 funcdraw()->String{

4 ifshapeisSquare{

5 returnshape.draw()

6 }

7 letlines=shape.draw().split(separator:"\n")

8 returnlines.reversed().joined(separator:"\n")

9 }

10 }

Therequirementtoalwaysreturnasingletypedoesn’tpreventyoufromusinggenericsinanopaquereturntype.Here’sanexampleofafunctionthatincorporatesitstypeparameterintotheunderlyingtypeofthevalueitreturns:

1 func`repeat`<T:Shape>(shape:T,count:Int)->some

Collection{

2 returnArray<T>(repeating:shape,count:count)

Page 455: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 }

Inthiscase,theunderlyingtypeofthereturnvaluevariesdependingonT:Whatevershapeispassedit,repeat(shape:count:)createsandreturnsanarrayofthatshape.Nevertheless,thereturnvaluealwayshasthesameunderlyingtypeof[T],soitfollowstherequirementthatfunctionswithopaquereturntypesmustreturnvaluesofonlyasingletype.

DifferencesBetweenOpaqueTypesandProtocolTypes

Returninganopaquetypelooksverysimilartousingaprotocoltypeasthereturntypeofafunction,butthesetwokindsofreturntypedifferinwhethertheypreservetypeidentity.Anopaquetypereferstoonespecifictype,althoughthecallerofthefunctionisn’tabletoseewhichtype;aprotocoltypecanrefertoanytypethatconformstotheprotocol.Generallyspeaking,protocoltypesgiveyoumoreflexibilityabouttheunderlyingtypesofthevaluestheystore,andopaquetypesletyoumakestrongerguaranteesaboutthoseunderlyingtypes.

Forexample,here’saversionofflip(_:)thatreturnsavalueofprotocoltypeinsteadofusinganopaquereturntype:

1 funcprotoFlip<T:Shape>(_shape:T)->Shape{

2 returnFlippedShape(shape:shape)

3 }

ThisversionofprotoFlip(_:)hasthesamebodyasflip(_:),anditalwaysreturnsavalueofthesametype.Unlikeflip(_:),thevaluethatprotoFlip(_:)returnsisn’trequiredtoalwayshavethesametype—itjusthastoconformtotheShapeprotocol.Putanotherway,protoFlip(_:)makesamuchlooserAPIcontractwithitscallerthanflip(_:)makes.Itreservestheflexibilitytoreturnvaluesofmultipletypes:

1 funcprotoFlip<T:Shape>(_shape:T)->Shape{

2 ifshapeisSquare{

Page 456: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 returnshape

4 }

5

6 returnFlippedShape(shape:shape)

7 }

TherevisedversionofthecodereturnsaninstanceofSquareoraninstanceofFlippedShape,dependingonwhatshapeispassedin.Twoflippedshapesreturnedbythisfunctionmighthavecompletelydifferenttypes.Othervalidversionsofthisfunctioncouldreturnvaluesofdifferenttypeswhenflippingmultipleinstancesofthesameshape.ThelessspecificreturntypeinformationfromprotoFlip(_:)meansthatmanyoperationsthatdependontypeinformationaren’tavailableonthereturnedvalue.Forexample,it’snotpossibletowritean==operatorcomparingresultsreturnedbythisfunction.

1 letprotoFlippedTriangle=protoFlip(smallTriangle)

2 letsameThing=protoFlip(smallTriangle)

3 protoFlippedTriangle==sameThing//Error

Theerroronthelastlineoftheexampleoccursforseveralreasons.TheimmediateissueisthattheShapedoesn’tincludean==operatoraspartofitsprotocolrequirements.Ifyoutryaddingone,thenextissueyou’llencounteristhatthe==operatorneedstoknowthetypesofitsleft-handandright-handarguments.ThissortofoperatorusuallytakesargumentsoftypeSelf,matchingwhateverconcretetypeadoptstheprotocol,butaddingaSelfrequirementtotheprotocoldoesn’tallowforthetypeerasurethathappenswhenyouusetheprotocolasatype.

Usingaprotocoltypeasthereturntypeforafunctiongivesyoutheflexibilitytoreturnanytypethatconformstotheprotocol.However,thecostofthatflexibilityisthatsomeoperationsaren’tpossibleonthereturnedvalues.Theexampleshowshowthe==operatorisn’tavailable—itdependsonspecifictypeinformationthatisn’tpreservedbyusingaprotocoltype.

Anotherproblemwiththisapproachisthattheshapetransformationsdon’tnest.

Page 457: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheresultofflippingatriangleisavalueoftypeShape,andtheprotoFlip(_:)functiontakesanargumentofsometypethatconformstotheShapeprotocol.However,avalueofaprotocoltypedoesn’tconformtothatprotocol;thevaluereturnedbyprotoFlip(_:)doesn’tconformtoShape.ThismeanscodelikeprotoFlip(protoFlip(smallTriange))thatappliesmultipletransformationsisinvalidbecausetheflippedshapeisn’tavalidargumenttoprotoFlip(_:).

Incontrast,opaquetypespreservetheidentityoftheunderlyingtype.Swiftcaninferassociatedtypes,whichletsyouuseanopaquereturnvalueinplaceswhereaprotocoltypecan’tbeusedasareturnvalue.Forexample,here’saversionoftheContainerprotocolfromGenerics:

1 protocolContainer{

2 associatedtypeItem

3 varcount:Int{get}

4 subscript(i:Int)->Item{get}

5 }

6 extensionArray:Container{}

Youcan’tuseContainerasthereturntypeofafunctionbecausethatprotocolhasanassociatedtype.Youalsocan’tuseitasconstraintagenericreturntypebecausethereisn’tenoughinformationoutsidethefunctionbodytoinferwhatthegenerictypeneedstobe.

1 //Error:Protocolwithassociatedtypescan'tbeusedasa

returntype.

2 funcmakeProtocolContainer<T>(item:T)->Container{

3 return[item]

4 }

5

6 //Error:NotenoughinformationtoinferC.

7 funcmakeProtocolContainer<T,C:Container>(item:T)->C{

8 return[item]

Page 458: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 }

UsingtheopaquetypesomeContainerasareturntypeexpressesthedesiredAPIcontract—thefunctionreturnsacontainer,butdeclinestospecifythecontainer’stype:

1 funcmakeOpaqueContainer<T>(item:T)->someContainer{

2 return[item]

3 }

4 letopaqueContainer=makeOpaqueContainer(item:12)

5 lettwelve=opaqueContainer[0]

6 print(type(of:twelve))

7 //Prints"Int"

ThetypeoftwelveisinferredtobeInt,whichillustratesthefactthattypeinferenceworkswithopaquetypes.IntheimplementationofmakeOpaqueContainer(item:),theunderlyingtypeoftheopaquecontaineris[T].Inthiscase,TisInt,sothereturnvalueisanarrayofintegersandtheItemassociatedtypeisinferredtobeInt.ThesubscriptonContainerreturnsItem,whichmeansthatthetypeoftwelveisalsoinferredtobeInt.

Page 459: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AutomaticReferenceCounting

SwiftusesAutomaticReferenceCounting(ARC)totrackandmanageyourapp’smemoryusage.Inmostcases,thismeansthatmemorymanagement“justworks”inSwift,andyoudonotneedtothinkaboutmemorymanagementyourself.ARCautomaticallyfreesupthememoryusedbyclassinstanceswhenthoseinstancesarenolongerneeded.

However,inafewcasesARCrequiresmoreinformationabouttherelationshipsbetweenpartsofyourcodeinordertomanagememoryforyou.ThischapterdescribesthosesituationsandshowshowyouenableARCtomanageallofyourapp’smemory.UsingARCinSwiftisverysimilartotheapproachdescribedinTransitioningtoARCReleaseNotesforusingARCwithObjective-C.

Referencecountingappliesonlytoinstancesofclasses.Structuresandenumerationsarevaluetypes,notreferencetypes,andarenotstoredandpassedbyreference.

HowARCWorks

Everytimeyoucreateanewinstanceofaclass,ARCallocatesachunkofmemorytostoreinformationaboutthatinstance.Thismemoryholdsinformationaboutthetypeoftheinstance,togetherwiththevaluesofanystoredpropertiesassociatedwiththatinstance.

Additionally,whenaninstanceisnolongerneeded,ARCfreesupthememoryusedbythatinstancesothatthememorycanbeusedforotherpurposesinstead.Thisensuresthatclassinstancesdonottakeupspaceinmemorywhentheyarenolongerneeded.

However,ifARCweretodeallocateaninstancethatwasstillinuse,itwouldnolongerbepossibletoaccessthatinstance’sproperties,orcallthatinstance’smethods.Indeed,ifyoutriedtoaccesstheinstance,yourappwouldmostlikelycrash.

Page 460: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Tomakesurethatinstancesdon’tdisappearwhiletheyarestillneeded,ARCtrackshowmanyproperties,constants,andvariablesarecurrentlyreferringtoeachclassinstance.ARCwillnotdeallocateaninstanceaslongasatleastoneactivereferencetothatinstancestillexists.

Tomakethispossible,wheneveryouassignaclassinstancetoaproperty,constant,orvariable,thatproperty,constant,orvariablemakesastrongreferencetotheinstance.Thereferenceiscalleda“strong”referencebecauseitkeepsafirmholdonthatinstance,anddoesnotallowittobedeallocatedforaslongasthatstrongreferenceremains.

ARCinAction

Here’sanexampleofhowAutomaticReferenceCountingworks.ThisexamplestartswithasimpleclasscalledPerson,whichdefinesastoredconstantpropertycalledname:

1 classPerson{

2 letname:String

3 init(name:String){

4 self.name=name

5 print("\(name)isbeinginitialized")

6 }

7 deinit{

8 print("\(name)isbeingdeinitialized")

9 }

10 }

ThePersonclasshasaninitializerthatsetstheinstance’snamepropertyandprintsamessagetoindicatethatinitializationisunderway.ThePersonclassalsohasadeinitializerthatprintsamessagewhenaninstanceoftheclassisdeallocated.

Page 461: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThenextcodesnippetdefinesthreevariablesoftypePerson?,whichareusedtosetupmultiplereferencestoanewPersoninstanceinsubsequentcodesnippets.Becausethesevariablesareofanoptionaltype(Person?,notPerson),theyareautomaticallyinitializedwithavalueofnil,anddonotcurrentlyreferenceaPersoninstance.

1 varreference1:Person?

2 varreference2:Person?

3 varreference3:Person?

YoucannowcreateanewPersoninstanceandassignittooneofthesethreevariables:

1 reference1=Person(name:"JohnAppleseed")

2 //Prints"JohnAppleseedisbeinginitialized"

Notethatthemessage"JohnAppleseedisbeinginitialized"isprintedatthepointthatyoucallthePersonclass’sinitializer.Thisconfirmsthatinitializationhastakenplace.

BecausethenewPersoninstancehasbeenassignedtothereference1variable,thereisnowastrongreferencefromreference1tothenewPersoninstance.Becausethereisatleastonestrongreference,ARCmakessurethatthisPersoniskeptinmemoryandisnotdeallocated.

IfyouassignthesamePersoninstancetotwomorevariables,twomorestrongreferencestothatinstanceareestablished:

1 reference2=reference1

2 reference3=reference1

TherearenowthreestrongreferencestothissinglePersoninstance.

Ifyoubreaktwoofthesestrongreferences(includingtheoriginalreference)byassigningniltotwoofthevariables,asinglestrongreferenceremains,andthePersoninstanceisnotdeallocated:

Page 462: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 reference1=nil

2 reference2=nil

ARCdoesnotdeallocatethePersoninstanceuntilthethirdandfinalstrongreferenceisbroken,atwhichpointit’sclearthatyouarenolongerusingthePersoninstance:

1 reference3=nil

2 //Prints"JohnAppleseedisbeingdeinitialized"

StrongReferenceCyclesBetweenClassInstances

Intheexamplesabove,ARCisabletotrackthenumberofreferencestothenewPersoninstanceyoucreateandtodeallocatethatPersoninstancewhenit’snolongerneeded.

However,it’spossibletowritecodeinwhichaninstanceofaclassnevergetstoapointwhereithaszerostrongreferences.Thiscanhappeniftwoclassinstancesholdastrongreferencetoeachother,suchthateachinstancekeepstheotheralive.Thisisknownasastrongreferencecycle.

Youresolvestrongreferencecyclesbydefiningsomeoftherelationshipsbetweenclassesasweakorunownedreferencesinsteadofasstrongreferences.ThisprocessisdescribedinResolvingStrongReferenceCyclesBetweenClassInstances.However,beforeyoulearnhowtoresolveastrongreferencecycle,it’susefultounderstandhowsuchacycleiscaused.

Here’sanexampleofhowastrongreferencecyclecanbecreatedbyaccident.ThisexampledefinestwoclassescalledPersonandApartment,whichmodelablockofapartmentsanditsresidents:

1 classPerson{

2 letname:String

Page 463: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 init(name:String){self.name=name}

4 varapartment:Apartment?

5 deinit{print("\(name)isbeingdeinitialized")}

6 }

7

8 classApartment{

9 letunit:String

10 init(unit:String){self.unit=unit}

11 vartenant:Person?

12 deinit{print("Apartment\(unit)isbeingdeinitialized")

}

13 }

EveryPersoninstancehasanamepropertyoftypeStringandanoptionalapartmentpropertythatisinitiallynil.Theapartmentpropertyisoptional,becauseapersonmaynotalwayshaveanapartment.

Similarly,everyApartmentinstancehasaunitpropertyoftypeStringandhasanoptionaltenantpropertythatisinitiallynil.Thetenantpropertyisoptionalbecauseanapartmentmaynotalwayshaveatenant.

Bothoftheseclassesalsodefineadeinitializer,whichprintsthefactthataninstanceofthatclassisbeingdeinitialized.ThisenablesyoutoseewhetherinstancesofPersonandApartmentarebeingdeallocatedasexpected.

Thisnextcodesnippetdefinestwovariablesofoptionaltypecalledjohnandunit4A,whichwillbesettoaspecificApartmentandPersoninstancebelow.Bothofthesevariableshaveaninitialvalueofnil,byvirtueofbeingoptional:

1 varjohn:Person?

2 varunit4A:Apartment?

YoucannowcreateaspecificPersoninstanceandApartmentinstanceandassignthesenewinstancestothejohnandunit4Avariables:

Page 464: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 john=Person(name:"JohnAppleseed")

2 unit4A=Apartment(unit:"4A")

Here’showthestrongreferenceslookaftercreatingandassigningthesetwoinstances.ThejohnvariablenowhasastrongreferencetothenewPersoninstance,andtheunit4AvariablehasastrongreferencetothenewApartmentinstance:

Youcannowlinkthetwoinstancestogethersothatthepersonhasanapartment,andtheapartmenthasatenant.Notethatanexclamationmark(!)isusedtounwrapandaccesstheinstancesstoredinsidethejohnandunit4Aoptionalvariables,sothatthepropertiesofthoseinstancescanbeset:

1 john!.apartment=unit4A

2 unit4A!.tenant=john

Here’showthestrongreferenceslookafteryoulinkthetwoinstancestogether:

Unfortunately,linkingthesetwoinstancescreatesastrongreferencecycle

Page 465: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

betweenthem.ThePersoninstancenowhasastrongreferencetotheApartmentinstance,andtheApartmentinstancehasastrongreferencetothePersoninstance.Therefore,whenyoubreakthestrongreferencesheldbythejohnandunit4Avariables,thereferencecountsdonotdroptozero,andtheinstancesarenotdeallocatedbyARC:

1 john=nil

2 unit4A=nil

Notethatneitherdeinitializerwascalledwhenyousetthesetwovariablestonil.ThestrongreferencecyclepreventsthePersonandApartmentinstancesfromeverbeingdeallocated,causingamemoryleakinyourapp.

Here’showthestrongreferenceslookafteryousetthejohnandunit4Avariablestonil:

ThestrongreferencesbetweenthePersoninstanceandtheApartmentinstanceremainandcannotbebroken.

ResolvingStrongReferenceCyclesBetweenClassInstances

Swiftprovidestwowaystoresolvestrongreferencecycleswhenyouworkwithpropertiesofclasstype:weakreferencesandunownedreferences.

Weakandunownedreferencesenableoneinstanceinareferencecycletorefertotheotherinstancewithoutkeepingastrongholdonit.Theinstancescanthen

Page 466: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

refertoeachotherwithoutcreatingastrongreferencecycle.

Useaweakreferencewhentheotherinstancehasashorterlifetime—thatis,whentheotherinstancecanbedeallocatedfirst.IntheApartmentexampleabove,it’sappropriateforanapartmenttobeabletohavenotenantatsomepointinitslifetime,andsoaweakreferenceisanappropriatewaytobreakthereferencecycleinthiscase.Incontrast,useanunownedreferencewhentheotherinstancehasthesamelifetimeoralongerlifetime.

WeakReferencesAweakreferenceisareferencethatdoesnotkeepastrongholdontheinstanceitrefersto,andsodoesnotstopARCfromdisposingofthereferencedinstance.Thisbehaviorpreventsthereferencefrombecomingpartofastrongreferencecycle.Youindicateaweakreferencebyplacingtheweakkeywordbeforeapropertyorvariabledeclaration.

Becauseaweakreferencedoesnotkeepastrongholdontheinstanceitrefersto,it’spossibleforthatinstancetobedeallocatedwhiletheweakreferenceisstillreferringtoit.Therefore,ARCautomaticallysetsaweakreferencetonilwhentheinstancethatitreferstoisdeallocated.And,becauseweakreferencesneedtoallowtheirvaluetobechangedtonilatruntime,theyarealwaysdeclaredasvariables,ratherthanconstants,ofanoptionaltype.

Youcancheckfortheexistenceofavalueintheweakreference,justlikeanyotheroptionalvalue,andyouwillneverendupwithareferencetoaninvalidinstancethatnolongerexists.

NOTE

Propertyobserversaren’tcalledwhenARCsetsaweakreferencetonil.

TheexamplebelowisidenticaltothePersonandApartmentexamplefromabove,withoneimportantdifference.Thistimearound,theApartmenttype’stenantpropertyisdeclaredasaweakreference:

1 classPerson{

Page 467: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 letname:String

3 init(name:String){self.name=name}

4 varapartment:Apartment?

5 deinit{print("\(name)isbeingdeinitialized")}

6 }

7

8 classApartment{

9 letunit:String

10 init(unit:String){self.unit=unit}

11 weakvartenant:Person?

12 deinit{print("Apartment\(unit)isbeingdeinitialized")

}

13 }

Thestrongreferencesfromthetwovariables(johnandunit4A)andthelinksbetweenthetwoinstancesarecreatedasbefore:

1 varjohn:Person?

2 varunit4A:Apartment?

3

4 john=Person(name:"JohnAppleseed")

5 unit4A=Apartment(unit:"4A")

6

7 john!.apartment=unit4A

8 unit4A!.tenant=john

Here’showthereferenceslooknowthatyou’velinkedthetwoinstancestogether:

Page 468: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThePersoninstancestillhasastrongreferencetotheApartmentinstance,buttheApartmentinstancenowhasaweakreferencetothePersoninstance.Thismeansthatwhenyoubreakthestrongreferenceheldbythejohnvariablebysettingittonil,therearenomorestrongreferencestothePersoninstance:

1 john=nil

2 //Prints"JohnAppleseedisbeingdeinitialized"

BecausetherearenomorestrongreferencestothePersoninstance,it’sdeallocatedandthetenantpropertyissettonil:

TheonlyremainingstrongreferencetotheApartmentinstanceisfromtheunit4Avariable.Ifyoubreakthatstrongreference,therearenomorestrongreferencestotheApartmentinstance:

1 unit4A=nil

2 //Prints"Apartment4Aisbeingdeinitialized"

BecausetherearenomorestrongreferencestotheApartmentinstance,ittoois

Page 469: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

deallocated:

NOTE

Insystemsthatusegarbagecollection,weakpointersaresometimesusedtoimplementasimplecachingmechanismbecauseobjectswithnostrongreferencesaredeallocatedonlywhenmemorypressuretriggersgarbagecollection.However,withARC,valuesaredeallocatedassoonastheirlaststrongreferenceisremoved,makingweakreferencesunsuitableforsuchapurpose.

UnownedReferencesLikeaweakreference,anunownedreferencedoesnotkeepastrongholdontheinstanceitrefersto.Unlikeaweakreference,however,anunownedreferenceisusedwhentheotherinstancehasthesamelifetimeoralongerlifetime.Youindicateanunownedreferencebyplacingtheunownedkeywordbeforeapropertyorvariabledeclaration.

Anunownedreferenceisexpectedtoalwayshaveavalue.Asaresult,ARCneversetsanunownedreference’svaluetonil,whichmeansthatunownedreferencesaredefinedusingnon-optionaltypes.

IMPORTANT

Useanunownedreferenceonlywhenyouaresurethatthereferencealwaysreferstoaninstancethathasnotbeendeallocated.

Ifyoutrytoaccessthevalueofanunownedreferenceafterthatinstancehasbeendeallocated,you’llgetaruntimeerror.

Thefollowingexampledefinestwoclasses,CustomerandCreditCard,whichmodelabankcustomerandapossiblecreditcardforthatcustomer.Thesetwo

Page 470: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

classeseachstoreaninstanceoftheotherclassasaproperty.Thisrelationshiphasthepotentialtocreateastrongreferencecycle.

TherelationshipbetweenCustomerandCreditCardisslightlydifferentfromtherelationshipbetweenApartmentandPersonseenintheweakreferenceexampleabove.Inthisdatamodel,acustomermayormaynothaveacreditcard,butacreditcardwillalwaysbeassociatedwithacustomer.ACreditCardinstanceneveroutlivestheCustomerthatitrefersto.Torepresentthis,theCustomerclasshasanoptionalcardproperty,buttheCreditCardclasshasanunowned(andnon-optional)customerproperty.

Furthermore,anewCreditCardinstancecanonlybecreatedbypassinganumbervalueandacustomerinstancetoacustomCreditCardinitializer.ThisensuresthataCreditCardinstancealwayshasacustomerinstanceassociatedwithitwhentheCreditCardinstanceiscreated.

Becauseacreditcardwillalwayshaveacustomer,youdefineitscustomerpropertyasanunownedreference,toavoidastrongreferencecycle:

1 classCustomer{

2 letname:String

3 varcard:CreditCard?

4 init(name:String){

5 self.name=name

6 }

7 deinit{print("\(name)isbeingdeinitialized")}

8 }

9

10 classCreditCard{

11 letnumber:UInt64

12 unownedletcustomer:Customer

13 init(number:UInt64,customer:Customer){

14 self.number=number

15 self.customer=customer

Page 471: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

16 }

17 deinit{print("Card#\(number)isbeingdeinitialized")}

18 }

NOTE

ThenumberpropertyoftheCreditCardclassisdefinedwithatypeofUInt64ratherthanInt,toensurethatthenumberproperty’scapacityislargeenoughtostorea16-digitcardnumberonboth32-bitand64-bitsystems.

ThisnextcodesnippetdefinesanoptionalCustomervariablecalledjohn,whichwillbeusedtostoreareferencetoaspecificcustomer.Thisvariablehasaninitialvalueofnil,byvirtueofbeingoptional:

varjohn:Customer?

YoucannowcreateaCustomerinstance,anduseittoinitializeandassignanewCreditCardinstanceasthatcustomer’scardproperty:

1 john=Customer(name:"JohnAppleseed")

2 john!.card=CreditCard(number:1234_5678_9012_3456,customer:

john!)

Here’showthereferenceslook,nowthatyou’velinkedthetwoinstances:

TheCustomerinstancenowhasastrongreferencetotheCreditCardinstance,andtheCreditCardinstancehasanunownedreferencetotheCustomerinstance.

Page 472: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Becauseoftheunownedcustomerreference,whenyoubreakthestrongreferenceheldbythejohnvariable,therearenomorestrongreferencestotheCustomerinstance:

BecausetherearenomorestrongreferencestotheCustomerinstance,it’sdeallocated.Afterthishappens,therearenomorestrongreferencestotheCreditCardinstance,andittooisdeallocated:

1 john=nil

2 //Prints"JohnAppleseedisbeingdeinitialized"

3 //Prints"Card#1234567890123456isbeingdeinitialized"

ThefinalcodesnippetaboveshowsthatthedeinitializersfortheCustomerinstanceandCreditCardinstancebothprinttheir“deinitialized”messagesafterthejohnvariableissettonil.

NOTE

Theexamplesaboveshowhowtousesafeunownedreferences.Swiftalsoprovidesunsafeunownedreferencesforcaseswhereyouneedtodisableruntimesafetychecks—forexample,forperformancereasons.Aswithallunsafeoperations,youtakeontheresponsibilityforcheckingthatcodeforsafety.

Youindicateanunsafeunownedreferencebywritingunowned(unsafe).Ifyoutrytoaccessanunsafeunownedreferenceaftertheinstancethatitreferstoisdeallocated,yourprogramwilltrytoaccessthememorylocationwheretheinstanceusedtobe,whichisanunsafeoperation.

UnownedReferencesandImplicitlyUnwrappedOptional

Page 473: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

PropertiesTheexamplesforweakandunownedreferencesabovecovertwoofthemorecommonscenariosinwhichit’snecessarytobreakastrongreferencecycle.

ThePersonandApartmentexampleshowsasituationwheretwoproperties,bothofwhichareallowedtobenil,havethepotentialtocauseastrongreferencecycle.Thisscenarioisbestresolvedwithaweakreference.

TheCustomerandCreditCardexampleshowsasituationwhereonepropertythatisallowedtobenilandanotherpropertythatcannotbenilhavethepotentialtocauseastrongreferencecycle.Thisscenarioisbestresolvedwithanunownedreference.

However,thereisathirdscenario,inwhichbothpropertiesshouldalwayshaveavalue,andneitherpropertyshouldeverbenilonceinitializationiscomplete.Inthisscenario,it’susefultocombineanunownedpropertyononeclasswithanimplicitlyunwrappedoptionalpropertyontheotherclass.

Thisenablesbothpropertiestobeaccesseddirectly(withoutoptionalunwrapping)onceinitializationiscomplete,whilestillavoidingareferencecycle.Thissectionshowsyouhowtosetupsucharelationship.

Theexamplebelowdefinestwoclasses,CountryandCity,eachofwhichstoresaninstanceoftheotherclassasaproperty.Inthisdatamodel,everycountrymustalwayshaveacapitalcity,andeverycitymustalwaysbelongtoacountry.Torepresentthis,theCountryclasshasacapitalCityproperty,andtheCityclasshasacountryproperty:

1 classCountry{

2 letname:String

3 varcapitalCity:City!

4 init(name:String,capitalName:String){

5 self.name=name

6 self.capitalCity=City(name:capitalName,country:

self)

7 }

Page 474: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 }

9

10 classCity{

11 letname:String

12 unownedletcountry:Country

13 init(name:String,country:Country){

14 self.name=name

15 self.country=country

16 }

17 }

Tosetuptheinterdependencybetweenthetwoclasses,theinitializerforCitytakesaCountryinstance,andstoresthisinstanceinitscountryproperty.

TheinitializerforCityiscalledfromwithintheinitializerforCountry.However,theinitializerforCountrycannotpassselftotheCityinitializeruntilanewCountryinstanceisfullyinitialized,asdescribedinTwo-PhaseInitialization.

Tocopewiththisrequirement,youdeclarethecapitalCitypropertyofCountryasanimplicitlyunwrappedoptionalproperty,indicatedbytheexclamationmarkattheendofitstypeannotation(City!).ThismeansthatthecapitalCitypropertyhasadefaultvalueofnil,likeanyotheroptional,butcanbeaccessedwithouttheneedtounwrapitsvalueasdescribedinImplicitlyUnwrappedOptionals.

BecausecapitalCityhasadefaultnilvalue,anewCountryinstanceisconsideredfullyinitializedassoonastheCountryinstancesetsitsnamepropertywithinitsinitializer.ThismeansthattheCountryinitializercanstarttoreferenceandpassaroundtheimplicitselfpropertyassoonasthenamepropertyisset.TheCountryinitializercanthereforepassselfasoneoftheparametersfortheCityinitializerwhentheCountryinitializerissettingitsowncapitalCityproperty.

AllofthismeansthatyoucancreatetheCountryandCityinstancesinasinglestatement,withoutcreatingastrongreferencecycle,andthecapitalCity

Page 475: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

propertycanbeaccesseddirectly,withoutneedingtouseanexclamationmarktounwrapitsoptionalvalue:

1 varcountry=Country(name:"Canada",capitalName:"Ottawa")

2 print("\(country.name)'scapitalcityiscalled\

(country.capitalCity.name)")

3 //Prints"Canada'scapitalcityiscalledOttawa"

Intheexampleabove,theuseofanimplicitlyunwrappedoptionalmeansthatallofthetwo-phaseclassinitializerrequirementsaresatisfied.ThecapitalCitypropertycanbeusedandaccessedlikeanon-optionalvalueonceinitializationiscomplete,whilestillavoidingastrongreferencecycle.

StrongReferenceCyclesforClosures

Yousawabovehowastrongreferencecyclecanbecreatedwhentwoclassinstancepropertiesholdastrongreferencetoeachother.Youalsosawhowtouseweakandunownedreferencestobreakthesestrongreferencecycles.

Astrongreferencecyclecanalsooccurifyouassignaclosuretoapropertyofaclassinstance,andthebodyofthatclosurecapturestheinstance.Thiscapturemightoccurbecausetheclosure’sbodyaccessesapropertyoftheinstance,suchasself.someProperty,orbecausetheclosurecallsamethodontheinstance,suchasself.someMethod().Ineithercase,theseaccessescausetheclosureto“capture”self,creatingastrongreferencecycle.

Thisstrongreferencecycleoccursbecauseclosures,likeclasses,arereferencetypes.Whenyouassignaclosuretoaproperty,youareassigningareferencetothatclosure.Inessence,it’sthesameproblemasabove—twostrongreferencesarekeepingeachotheralive.However,ratherthantwoclassinstances,thistimeit’saclassinstanceandaclosurethatarekeepingeachotheralive.

Swiftprovidesanelegantsolutiontothisproblem,knownasaclosurecapturelist.However,beforeyoulearnhowtobreakastrongreferencecyclewitha

Page 476: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

closurecapturelist,it’susefultounderstandhowsuchacyclecanbecaused.

Theexamplebelowshowshowyoucancreateastrongreferencecyclewhenusingaclosurethatreferencesself.ThisexampledefinesaclasscalledHTMLElement,whichprovidesasimplemodelforanindividualelementwithinanHTMLdocument:

1 classHTMLElement{

2

3 letname:String

4 lettext:String?

5

6 lazyvarasHTML:()->String={

7 iflettext=self.text{

8 return"<\(self.name)>\(text)</\(self.name)>"

9 }else{

10 return"<\(self.name)/>"

11 }

12 }

13

14 init(name:String,text:String?=nil){

15 self.name=name

16 self.text=text

17 }

18

19 deinit{

20 print("\(name)isbeingdeinitialized")

21 }

22

23 }

Page 477: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheHTMLElementclassdefinesanameproperty,whichindicatesthenameoftheelement,suchas"h1"foraheadingelement,"p"foraparagraphelement,or"br"foralinebreakelement.HTMLElementalsodefinesanoptionaltextproperty,whichyoucansettoastringthatrepresentsthetexttoberenderedwithinthatHTMLelement.

Inadditiontothesetwosimpleproperties,theHTMLElementclassdefinesalazypropertycalledasHTML.ThispropertyreferencesaclosurethatcombinesnameandtextintoanHTMLstringfragment.TheasHTMLpropertyisoftype()->String,or“afunctionthattakesnoparameters,andreturnsaStringvalue”.

Bydefault,theasHTMLpropertyisassignedaclosurethatreturnsastringrepresentationofanHTMLtag.Thistagcontainstheoptionaltextvalueifitexists,ornotextcontentiftextdoesnotexist.Foraparagraphelement,theclosurewouldreturn"<p>sometext</p>"or"<p/>",dependingonwhetherthetextpropertyequals"sometext"ornil.

TheasHTMLpropertyisnamedandusedsomewhatlikeaninstancemethod.However,becauseasHTMLisaclosurepropertyratherthananinstancemethod,youcanreplacethedefaultvalueoftheasHTMLpropertywithacustomclosure,ifyouwanttochangetheHTMLrenderingforaparticularHTMLelement.

Forexample,theasHTMLpropertycouldbesettoaclosurethatdefaultstosometextifthetextpropertyisnil,inordertopreventtherepresentationfromreturninganemptyHTMLtag:

1 letheading=HTMLElement(name:"h1")

2 letdefaultText="somedefaulttext"

3 heading.asHTML={

4 return"<\(heading.name)>\(heading.text??defaultText)</\

(heading.name)>"

5 }

6 print(heading.asHTML())

7 //Prints"<h1>somedefaulttext</h1>"

NOTE

Page 478: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheasHTMLpropertyisdeclaredasalazyproperty,becauseit’sonlyneededifandwhentheelementactuallyneedstoberenderedasastringvalueforsomeHTMLoutputtarget.ThefactthatasHTMLisalazypropertymeansthatyoucanrefertoselfwithinthedefaultclosure,becausethelazypropertywillnotbeaccesseduntilafterinitializationhasbeencompletedandselfisknowntoexist.

TheHTMLElementclassprovidesasingleinitializer,whichtakesanameargumentand(ifdesired)atextargumenttoinitializeanewelement.Theclassalsodefinesadeinitializer,whichprintsamessagetoshowwhenanHTMLElementinstanceisdeallocated.

Here’showyouusetheHTMLElementclasstocreateandprintanewinstance:

1 varparagraph:HTMLElement?=HTMLElement(name:"p",text:

"hello,world")

2 print(paragraph!.asHTML())

3 //Prints"<p>hello,world</p>"

NOTE

TheparagraphvariableaboveisdefinedasanoptionalHTMLElement,sothatitcanbesettonilbelowtodemonstratethepresenceofastrongreferencecycle.

Unfortunately,theHTMLElementclass,aswrittenabove,createsastrongreferencecyclebetweenanHTMLElementinstanceandtheclosureusedforitsdefaultasHTMLvalue.Here’showthecyclelooks:

Page 479: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theinstance’sasHTMLpropertyholdsastrongreferencetoitsclosure.However,becausetheclosurereferstoselfwithinitsbody(asawaytoreferenceself.nameandself.text),theclosurecapturesself,whichmeansthatitholdsastrongreferencebacktotheHTMLElementinstance.Astrongreferencecycleiscreatedbetweenthetwo.(Formoreinformationaboutcapturingvaluesinaclosure,seeCapturingValues.)

NOTE

Eventhoughtheclosurereferstoselfmultipletimes,itonlycapturesonestrongreferencetotheHTMLElementinstance.

IfyousettheparagraphvariabletonilandbreakitsstrongreferencetotheHTMLElementinstance,neithertheHTMLElementinstancenoritsclosurearedeallocated,becauseofthestrongreferencecycle:

paragraph=nil

NotethatthemessageintheHTMLElementdeinitializerisnotprinted,whichshowsthattheHTMLElementinstanceisnotdeallocated.

ResolvingStrongReferenceCyclesforClosures

Youresolveastrongreferencecyclebetweenaclosureandaclassinstancebydefiningacapturelistaspartoftheclosure’sdefinition.Acapturelistdefinestherulestousewhencapturingoneormorereferencetypeswithintheclosure’sbody.Aswithstrongreferencecyclesbetweentwoclassinstances,youdeclareeachcapturedreferencetobeaweakorunownedreferenceratherthanastrongreference.Theappropriatechoiceofweakorunowneddependsontherelationshipsbetweenthedifferentpartsofyourcode.

NOTE

Swiftrequiresyoutowriteself.somePropertyorself.someMethod()(ratherthanjustsomePropertyorsomeMethod())wheneveryourefertoamemberofselfwithinaclosure.Thishelpsyourememberthatit’spossibletocaptureselfbyaccident.

Page 480: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

DefiningaCaptureListEachiteminacapturelistisapairingoftheweakorunownedkeywordwithareferencetoaclassinstance(suchasself)oravariableinitializedwithsomevalue(suchasdelegate=self.delegate).Thesepairingsarewrittenwithinapairofsquarebraces,separatedbycommas.

Placethecapturelistbeforeaclosure’sparameterlistandreturntypeiftheyareprovided:

1 lazyvarsomeClosure={

2 [unownedself,weakdelegate=self.delegate]

3 (index:Int,stringToProcess:String)->Stringin

4 //closurebodygoeshere

5 }

Ifaclosuredoesnotspecifyaparameterlistorreturntypebecausetheycanbeinferredfromcontext,placethecapturelistattheverystartoftheclosure,followedbytheinkeyword:

1 lazyvarsomeClosure={

2 [unownedself,weakdelegate=self.delegate]in

3 //closurebodygoeshere

4 }

WeakandUnownedReferencesDefineacaptureinaclosureasanunownedreferencewhentheclosureandtheinstanceitcaptureswillalwaysrefertoeachother,andwillalwaysbedeallocatedatthesametime.

Conversely,defineacaptureasaweakreferencewhenthecapturedreferencemaybecomenilatsomepointinthefuture.Weakreferencesarealwaysofanoptionaltype,andautomaticallybecomenilwhentheinstancetheyreferenceisdeallocated.Thisenablesyoutocheckfortheirexistencewithintheclosure’s

Page 481: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

body.

NOTE

Ifthecapturedreferencewillneverbecomenil,itshouldalwaysbecapturedasanunownedreference,ratherthanaweakreference.

AnunownedreferenceistheappropriatecapturemethodtousetoresolvethestrongreferencecycleintheHTMLElementexamplefromStrongReferenceCyclesforClosuresabove.Here’showyouwritetheHTMLElementclasstoavoidthecycle:

1 classHTMLElement{

2

3 letname:String

4 lettext:String?

5

6 lazyvarasHTML:()->String={

7 [unownedself]in

8 iflettext=self.text{

9 return"<\(self.name)>\(text)</\(self.name)>"

10 }else{

11 return"<\(self.name)/>"

12 }

13 }

14

15 init(name:String,text:String?=nil){

16 self.name=name

17 self.text=text

18 }

19

20 deinit{

Page 482: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

21 print("\(name)isbeingdeinitialized")

22 }

23

24 }

ThisimplementationofHTMLElementisidenticaltothepreviousimplementation,apartfromtheadditionofacapturelistwithintheasHTMLclosure.Inthiscase,thecapturelistis[unownedself],whichmeans“captureselfasanunownedreferenceratherthanastrongreference”.

YoucancreateandprintanHTMLElementinstanceasbefore:

1 varparagraph:HTMLElement?=HTMLElement(name:"p",text:

"hello,world")

2 print(paragraph!.asHTML())

3 //Prints"<p>hello,world</p>"

Here’showthereferenceslookwiththecapturelistinplace:

Thistime,thecaptureofselfbytheclosureisanunownedreference,anddoesnotkeepastrongholdontheHTMLElementinstanceithascaptured.Ifyousetthestrongreferencefromtheparagraphvariabletonil,theHTMLElementinstanceisdeallocated,ascanbeseenfromtheprintingofitsdeinitializermessageintheexamplebelow:

Page 483: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 paragraph=nil

2 //Prints"pisbeingdeinitialized"

Formoreinformationaboutcapturelists,seeCaptureLists.

Page 484: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

MemorySafety

Bydefault,Swiftpreventsunsafebehaviorfromhappeninginyourcode.Forexample,Swiftensuresthatvariablesareinitializedbeforethey’reused,memoryisn’taccessedafterit’sbeendeallocated,andarrayindicesarecheckedforout-of-boundserrors.

Swiftalsomakessurethatmultipleaccessestothesameareaofmemorydon’tconflict,byrequiringcodethatmodifiesalocationinmemorytohaveexclusiveaccesstothatmemory.BecauseSwiftmanagesmemoryautomatically,mostofthetimeyoudon’thavetothinkaboutaccessingmemoryatall.However,it’simportanttounderstandwherepotentialconflictscanoccur,soyoucanavoidwritingcodethathasconflictingaccesstomemory.Ifyourcodedoescontainconflicts,you’llgetacompile-timeorruntimeerror.

UnderstandingConflictingAccesstoMemory

Accesstomemoryhappensinyourcodewhenyoudothingslikesetthevalueofavariableorpassanargumenttoafunction.Forexample,thefollowingcodecontainsbothareadaccessandawriteaccess:

1 //Awriteaccesstothememorywhereoneisstored.

2 varone=1

3

4 //Areadaccessfromthememorywhereoneisstored.

5 print("We'renumber\(one)!")

Aconflictingaccesstomemorycanoccurwhendifferentpartsofyourcodearetryingtoaccessthesamelocationinmemoryatthesametime.Multipleaccessestoalocationinmemoryatthesametimecanproduceunpredictableorinconsistentbehavior.InSwift,therearewaystomodifyavaluethatspanseverallinesofcode,makingitpossibletoattempttoaccessavalueinthe

Page 485: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

middleofitsownmodification.

Youcanseeasimilarproblembythinkingabouthowyouupdateabudgetthat’swrittenonapieceofpaper.Updatingthebudgetisatwo-stepprocess:Firstyouaddtheitems’namesandprices,andthenyouchangethetotalamounttoreflecttheitemscurrentlyonthelist.Beforeandaftertheupdate,youcanreadanyinformationfromthebudgetandgetacorrectanswer,asshowninthefigurebelow.

Whileyou’readdingitemstothebudget,it’sinatemporary,invalidstatebecausethetotalamounthasn’tbeenupdatedtoreflectthenewlyaddeditems.Readingthetotalamountduringtheprocessofaddinganitemgivesyouincorrectinformation.

Thisexamplealsodemonstratesachallengeyoumayencounterwhenfixingconflictingaccesstomemory:Therearesometimesmultiplewaystofixtheconflictthatproducedifferentanswers,andit’snotalwaysobviouswhichansweriscorrect.Inthisexample,dependingonwhetheryouwantedtheoriginaltotalamountortheupdatedtotalamount,either$5or$320couldbethecorrectanswer.Beforeyoucanfixtheconflictingaccess,youhavetodeterminewhatitwasintendedtodo.

NOTE

Ifyou’vewrittenconcurrentormultithreadedcode,conflictingaccesstomemorymightbeafamiliarproblem.However,theconflictingaccessdiscussedherecanhappenonasinglethreadanddoesn’tinvolveconcurrentormultithreadedcode.

Ifyouhaveconflictingaccesstomemoryfromwithinasinglethread,Swiftguaranteesthatyou’llgetanerrorateithercompiletimeorruntime.Formultithreadedcode,useThreadSanitizertohelpdetectconflictingaccessacrossthreads.

Page 486: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

CharacteristicsofMemoryAccessTherearethreecharacteristicsofmemoryaccesstoconsiderinthecontextofconflictingaccess:whethertheaccessisareadorawrite,thedurationoftheaccess,andthelocationinmemorybeingaccessed.Specifically,aconflictoccursifyouhavetwoaccessesthatmeetallofthefollowingconditions:

Atleastoneisawriteaccess.

Theyaccessthesamelocationinmemory.

Theirdurationsoverlap.

Thedifferencebetweenareadandwriteaccessisusuallyobvious:awriteaccesschangesthelocationinmemory,butareadaccessdoesn’t.Thelocationinmemoryreferstowhatisbeingaccessed—forexample,avariable,constant,orproperty.Thedurationofamemoryaccessiseitherinstantaneousorlong-term.

Anaccessisinstantaneousifit’snotpossibleforothercodetorunafterthataccessstartsbutbeforeitends.Bytheirnature,twoinstantaneousaccessescan’thappenatthesametime.Mostmemoryaccessisinstantaneous.Forexample,allthereadandwriteaccessesinthecodelistingbelowareinstantaneous:

1 funconeMore(thannumber:Int)->Int{

2 returnnumber+1

3 }

4

5 varmyNumber=1

6 myNumber=oneMore(than:myNumber)

7 print(myNumber)

8 //Prints"2"

However,thereareseveralwaystoaccessmemory,calledlong-termaccesses,thatspantheexecutionofothercode.Thedifferencebetweeninstantaneousaccessandlong-termaccessisthatit’spossibleforothercodetorunafteralong-termaccessstartsbutbeforeitends,whichiscalledoverlap.Along-termaccesscanoverlapwithotherlong-termaccessesandinstantaneousaccesses.

Page 487: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Overlappingaccessesappearprimarilyincodethatusesin-outparametersinfunctionsandmethodsormutatingmethodsofastructure.ThespecifickindsofSwiftcodethatuselong-termaccessesarediscussedinthesectionsbelow.

ConflictingAccesstoIn-OutParameters

Afunctionhaslong-termwriteaccesstoallofitsin-outparameters.Thewriteaccessforanin-outparameterstartsafterallofthenon-in-outparametershavebeenevaluatedandlastsfortheentiredurationofthatfunctioncall.Iftherearemultiplein-outparameters,thewriteaccessesstartinthesameorderastheparametersappear.

Oneconsequenceofthislong-termwriteaccessisthatyoucan’taccesstheoriginalvariablethatwaspassedasin-out,evenifscopingrulesandaccesscontrolwouldotherwisepermitit—anyaccesstotheoriginalcreatesaconflict.Forexample:

1 varstepSize=1

2

3 funcincrement(_number:inoutInt){

4 number+=stepSize

5 }

6

7 increment(&stepSize)

8 //Error:conflictingaccessestostepSize

Inthecodeabove,stepSizeisaglobalvariable,anditisnormallyaccessiblefromwithinincrement(_:).However,thereadaccesstostepSizeoverlapswiththewriteaccesstonumber.Asshowninthefigurebelow,bothnumberandstepSizerefertothesamelocationinmemory.Thereadandwriteaccessesrefertothesamememoryandtheyoverlap,producingaconflict.

Page 488: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

OnewaytosolvethisconflictistomakeanexplicitcopyofstepSize:

1 //Makeanexplicitcopy.

2 varcopyOfStepSize=stepSize

3 increment(&copyOfStepSize)

4

5 //Updatetheoriginal.

6 stepSize=copyOfStepSize

7 //stepSizeisnow2

WhenyoumakeacopyofstepSizebeforecallingincrement(_:),it’sclearthatthevalueofcopyOfStepSizeisincrementedbythecurrentstepsize.Thereadaccessendsbeforethewriteaccessstarts,sothereisn’taconflict.

Anotherconsequenceoflong-termwriteaccesstoin-outparametersisthatpassingasinglevariableastheargumentformultiplein-outparametersofthesamefunctionproducesaconflict.Forexample:

1 funcbalance(_x:inoutInt,_y:inoutInt){

2 letsum=x+y

3 x=sum/2

4 y=sum-x

5 }

6 varplayerOneScore=42

7 varplayerTwoScore=30

8 balance(&playerOneScore,&playerTwoScore)//OK

9 balance(&playerOneScore,&playerOneScore)

Page 489: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

10 //Error:conflictingaccessestoplayerOneScore

Thebalance(_:_:)functionabovemodifiesitstwoparameterstodividethetotalvalueevenlybetweenthem.CallingitwithplayerOneScoreandplayerTwoScoreasargumentsdoesn’tproduceaconflict—therearetwowriteaccessesthatoverlapintime,buttheyaccessdifferentlocationsinmemory.Incontrast,passingplayerOneScoreasthevalueforbothparametersproducesaconflictbecauseittriestoperformtwowriteaccessestothesamelocationinmemoryatthesametime.

NOTE

Becauseoperatorsarefunctions,theycanalsohavelong-termaccessestotheirin-outparameters.Forexample,ifbalance(_:_:)wasanoperatorfunctionnamed<^>,writingplayerOneScore<^>playerOneScorewouldresultinthesameconflictasbalance(&playerOneScore,&playerOneScore).

ConflictingAccesstoselfinMethods

Amutatingmethodonastructurehaswriteaccesstoselfforthedurationofthemethodcall.Forexample,consideragamewhereeachplayerhasahealthamount,whichdecreaseswhentakingdamage,andanenergyamount,whichdecreaseswhenusingspecialabilities.

1 structPlayer{

2 varname:String

3 varhealth:Int

4 varenergy:Int

5

6 staticletmaxHealth=10

7 mutatingfuncrestoreHealth(){

8 health=Player.maxHealth

9 }

Page 490: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

10 }

IntherestoreHealth()methodabove,awriteaccesstoselfstartsatthebeginningofthemethodandlastsuntilthemethodreturns.Inthiscase,there’snoothercodeinsiderestoreHealth()thatcouldhaveanoverlappingaccesstothepropertiesofaPlayerinstance.TheshareHealth(with:)methodbelowtakesanotherPlayerinstanceasanin-outparameter,creatingthepossibilityofoverlappingaccesses.

1 extensionPlayer{

2 mutatingfuncshareHealth(withteammate:inoutPlayer){

3 balance(&teammate.health,&health)

4 }

5 }

6

7 varoscar=Player(name:"Oscar",health:10,energy:10)

8 varmaria=Player(name:"Maria",health:5,energy:10)

9 oscar.shareHealth(with:&maria)//OK

Intheexampleabove,callingtheshareHealth(with:)methodforOscar’splayertosharehealthwithMaria’splayerdoesn’tcauseaconflict.There’sawriteaccesstooscarduringthemethodcallbecauseoscaristhevalueofselfinamutatingmethod,andthere’sawriteaccesstomariaforthesamedurationbecausemariawaspassedasanin-outparameter.Asshowninthefigurebelow,theyaccessdifferentlocationsinmemory.Eventhoughthetwowriteaccessesoverlapintime,theydon’tconflict.

Page 491: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

However,ifyoupassoscarastheargumenttoshareHealth(with:),there’saconflict:

1 oscar.shareHealth(with:&oscar)

2 //Error:conflictingaccessestooscar

Themutatingmethodneedswriteaccesstoselfforthedurationofthemethod,andthein-outparameterneedswriteaccesstoteammateforthesameduration.Withinthemethod,bothselfandteammaterefertothesamelocationinmemory—asshowninthefigurebelow.Thetwowriteaccessesrefertothesamememoryandtheyoverlap,producingaconflict.

ConflictingAccesstoProperties

Typeslikestructures,tuples,andenumerationsaremadeupofindividualconstituentvalues,suchasthepropertiesofastructureortheelementsofatuple.Becausethesearevaluetypes,mutatinganypieceofthevaluemutatesthewholevalue,meaningreadorwriteaccesstooneofthepropertiesrequiresreadorwriteaccesstothewholevalue.Forexample,overlappingwriteaccessestotheelementsofatupleproducesaconflict:

1 varplayerInformation=(health:10,energy:20)

2 balance(&playerInformation.health,&playerInformation.energy)

3 //Error:conflictingaccesstopropertiesofplayerInformation

Intheexampleabove,callingbalance(_:_:)ontheelementsofatupleproduces

Page 492: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

aconflictbecausethereareoverlappingwriteaccessestoplayerInformation.BothplayerInformation.healthandplayerInformation.energyarepassedasin-outparameters,whichmeansbalance(_:_:)needswriteaccesstothemforthedurationofthefunctioncall.Inbothcases,awriteaccesstothetupleelementrequiresawriteaccesstotheentiretuple.ThismeanstherearetwowriteaccessestoplayerInformationwithdurationsthatoverlap,causingaconflict.

Thecodebelowshowsthatthesameerrorappearsforoverlappingwriteaccessestothepropertiesofastructurethat’sstoredinaglobalvariable.

1 varholly=Player(name:"Holly",health:10,energy:10)

2 balance(&holly.health,&holly.energy)//Error

Inpractice,mostaccesstothepropertiesofastructurecanoverlapsafely.Forexample,ifthevariablehollyintheexampleaboveischangedtoalocalvariableinsteadofaglobalvariable,thecompilercanprovethatoverlappingaccesstostoredpropertiesofthestructureissafe:

1 funcsomeFunction(){

2 varoscar=Player(name:"Oscar",health:10,energy:10)

3 balance(&oscar.health,&oscar.energy)//OK

4 }

Intheexampleabove,Oscar’shealthandenergyarepassedasthetwoin-outparameterstobalance(_:_:).Thecompilercanprovethatmemorysafetyispreservedbecausethetwostoredpropertiesdon’tinteractinanyway.

Therestrictionagainstoverlappingaccesstopropertiesofastructureisn’talwaysnecessarytopreservememorysafety.Memorysafetyisthedesiredguarantee,butexclusiveaccessisastricterrequirementthanmemorysafety—whichmeanssomecodepreservesmemorysafety,eventhoughitviolatesexclusiveaccesstomemory.Swiftallowsthismemory-safecodeifthecompilercanprovethatthenonexclusiveaccesstomemoryisstillsafe.Specifically,itcanprovethatoverlappingaccesstopropertiesofastructureissafeifthefollowingconditionsapply:

Page 493: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

You’reaccessingonlystoredpropertiesofaninstance,notcomputedpropertiesorclassproperties.

Thestructureisthevalueofalocalvariable,notaglobalvariable.

Thestructureiseithernotcapturedbyanyclosures,orit’scapturedonlybynonescapingclosures.

Ifthecompilercan’tprovetheaccessissafe,itdoesn’tallowtheaccess.

Page 494: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AccessControl

Accesscontrolrestrictsaccesstopartsofyourcodefromcodeinothersourcefilesandmodules.Thisfeatureenablesyoutohidetheimplementationdetailsofyourcode,andtospecifyapreferredinterfacethroughwhichthatcodecanbeaccessedandused.

Youcanassignspecificaccesslevelstoindividualtypes(classes,structures,andenumerations),aswellastoproperties,methods,initializers,andsubscriptsbelongingtothosetypes.Protocolscanberestrictedtoacertaincontext,ascanglobalconstants,variables,andfunctions.

Inadditiontoofferingvariouslevelsofaccesscontrol,Swiftreducestheneedtospecifyexplicitaccesscontrollevelsbyprovidingdefaultaccesslevelsfortypicalscenarios.Indeed,ifyouarewritingasingle-targetapp,youmaynotneedtospecifyexplicitaccesscontrollevelsatall.

NOTE

Thevariousaspectsofyourcodethatcanhaveaccesscontrolappliedtothem(properties,types,functions,andsoon)arereferredtoas“entities”inthesectionsbelow,forbrevity.

ModulesandSourceFiles

Swift’saccesscontrolmodelisbasedontheconceptofmodulesandsourcefiles.

Amoduleisasingleunitofcodedistribution—aframeworkorapplicationthatisbuiltandshippedasasingleunitandthatcanbeimportedbyanothermodulewithSwift’simportkeyword.

Eachbuildtarget(suchasanappbundleorframework)inXcodeistreatedasaseparatemoduleinSwift.Ifyougrouptogetheraspectsofyourapp’scodeasastand-aloneframework—perhapstoencapsulateandreusethatcodeacrossmultipleapplications—theneverythingyoudefinewithinthatframeworkwillbe

Page 495: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

partofaseparatemodulewhenit’simportedandusedwithinanapp,orwhenit’susedwithinanotherframework.

AsourcefileisasingleSwiftsourcecodefilewithinamodule(ineffect,asinglefilewithinanapporframework).Althoughit’scommontodefineindividualtypesinseparatesourcefiles,asinglesourcefilecancontaindefinitionsformultipletypes,functions,andsoon.

AccessLevels

Swiftprovidesfivedifferentaccesslevelsforentitieswithinyourcode.Theseaccesslevelsarerelativetothesourcefileinwhichanentityisdefined,andalsorelativetothemodulethatsourcefilebelongsto.

Openaccessandpublicaccessenableentitiestobeusedwithinanysourcefilefromtheirdefiningmodule,andalsoinasourcefilefromanothermodulethatimportsthedefiningmodule.Youtypicallyuseopenorpublicaccesswhenspecifyingthepublicinterfacetoaframework.Thedifferencebetweenopenandpublicaccessisdescribedbelow.

Internalaccessenablesentitiestobeusedwithinanysourcefilefromtheirdefiningmodule,butnotinanysourcefileoutsideofthatmodule.Youtypicallyuseinternalaccesswhendefininganapp’soraframework’sinternalstructure.

File-privateaccessrestrictstheuseofanentitytoitsowndefiningsourcefile.Usefile-privateaccesstohidetheimplementationdetailsofaspecificpieceoffunctionalitywhenthosedetailsareusedwithinanentirefile.

Privateaccessrestrictstheuseofanentitytotheenclosingdeclaration,andtoextensionsofthatdeclarationthatareinthesamefile.Useprivateaccesstohidetheimplementationdetailsofaspecificpieceoffunctionalitywhenthosedetailsareusedonlywithinasingledeclaration.

Openaccessisthehighest(leastrestrictive)accesslevelandprivateaccessisthelowest(mostrestrictive)accesslevel.

Page 496: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Openaccessappliesonlytoclassesandclassmembers,anditdiffersfrompublicaccessbyallowingcodeoutsidethemoduletosubclassandoverride,asdiscussedbelowinSubclassing.Markingaclassasopenexplicitlyindicatesthatyou’veconsideredtheimpactofcodefromothermodulesusingthatclassasasuperclass,andthatyou’vedesignedyourclass’scodeaccordingly.

GuidingPrincipleofAccessLevelsAccesslevelsinSwiftfollowanoverallguidingprinciple:Noentitycanbedefinedintermsofanotherentitythathasalower(morerestrictive)accesslevel.

Forexample:

Apublicvariablecan’tbedefinedashavinganinternal,file-private,orprivatetype,becausethetypemightnotbeavailableeverywherethatthepublicvariableisused.

Afunctioncan’thaveahigheraccesslevelthanitsparametertypesandreturntype,becausethefunctioncouldbeusedinsituationswhereitsconstituenttypesareunavailabletothesurroundingcode.

Thespecificimplicationsofthisguidingprinciplefordifferentaspectsofthelanguagearecoveredindetailbelow.

DefaultAccessLevelsAllentitiesinyourcode(withafewspecificexceptions,asdescribedlaterinthischapter)haveadefaultaccesslevelofinternalifyoudon’tspecifyanexplicitaccesslevelyourself.Asaresult,inmanycasesyoudon’tneedtospecifyanexplicitaccesslevelinyourcode.

AccessLevelsforSingle-TargetAppsWhenyouwriteasimplesingle-targetapp,thecodeinyourappistypicallyself-containedwithintheappanddoesn’tneedtobemadeavailableoutsideofthe

Page 497: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

app’smodule.Thedefaultaccesslevelofinternalalreadymatchesthisrequirement.Therefore,youdon’tneedtospecifyacustomaccesslevel.Youmay,however,wanttomarksomepartsofyourcodeasfileprivateorprivateinordertohidetheirimplementationdetailsfromothercodewithintheapp’smodule.

AccessLevelsforFrameworksWhenyoudevelopaframework,markthepublic-facinginterfacetothatframeworkasopenorpublicsothatitcanbeviewedandaccessedbyothermodules,suchasanappthatimportstheframework.Thispublic-facinginterfaceistheapplicationprogramminginterface(orAPI)fortheframework.

NOTE

Anyinternalimplementationdetailsofyourframeworkcanstillusethedefaultaccesslevelofinternal,orcanbemarkedasprivateorfileprivateifyouwanttohidethemfromotherpartsoftheframework’sinternalcode.Youneedtomarkanentityasopenorpubliconlyifyouwantittobecomepartofyourframework’sAPI.

AccessLevelsforUnitTestTargetsWhenyouwriteanappwithaunittesttarget,thecodeinyourappneedstobemadeavailabletothatmoduleinordertobetested.Bydefault,onlyentitiesmarkedasopenorpublicareaccessibletoothermodules.However,aunittesttargetcanaccessanyinternalentity,ifyoumarktheimportdeclarationforaproductmodulewiththe@testableattributeandcompilethatproductmodulewithtestingenabled.

AccessControlSyntax

Definetheaccesslevelforanentitybyplacingoneoftheopen,public,internal,fileprivate,orprivatemodifiersatthebeginningoftheentity’sdeclaration.

Page 498: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 publicclassSomePublicClass{}

2 internalclassSomeInternalClass{}

3 fileprivateclassSomeFilePrivateClass{}

4 privateclassSomePrivateClass{}

5

6 publicvarsomePublicVariable=0

7 internalletsomeInternalConstant=0

8 fileprivatefuncsomeFilePrivateFunction(){}

9 privatefuncsomePrivateFunction(){}

Unlessotherwisespecified,thedefaultaccesslevelisinternal,asdescribedinDefaultAccessLevels.ThismeansthatSomeInternalClassandsomeInternalConstantcanbewrittenwithoutanexplicitaccess-levelmodifier,andwillstillhaveanaccesslevelofinternal:

1 classSomeInternalClass{}//implicitlyinternal

2 letsomeInternalConstant=0//implicitlyinternal

CustomTypes

Ifyouwanttospecifyanexplicitaccesslevelforacustomtype,dosoatthepointthatyoudefinethetype.Thenewtypecanthenbeusedwhereveritsaccesslevelpermits.Forexample,ifyoudefineafile-privateclass,thatclasscanonlybeusedasthetypeofaproperty,orasafunctionparameterorreturntype,inthesourcefileinwhichthefile-privateclassisdefined.

Theaccesscontrollevelofatypealsoaffectsthedefaultaccesslevelofthattype’smembers(itsproperties,methods,initializers,andsubscripts).Ifyoudefineatype’saccesslevelasprivateorfileprivate,thedefaultaccesslevelofitsmemberswillalsobeprivateorfileprivate.Ifyoudefineatype’saccesslevelasinternalorpublic(orusethedefaultaccesslevelofinternalwithoutspecifyinganaccesslevelexplicitly),thedefaultaccesslevelofthetype’s

Page 499: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

memberswillbeinternal.

IMPORTANT

Apublictypedefaultstohavinginternalmembers,notpublicmembers.Ifyouwantatypemembertobepublic,youmustexplicitlymarkitassuch.Thisrequirementensuresthatthepublic-facingAPIforatypeissomethingyouoptintopublishing,andavoidspresentingtheinternalworkingsofatypeaspublicAPIbymistake.

1 publicclassSomePublicClass{//explicitly

publicclass

2 publicvarsomePublicProperty=0//explicitly

publicclassmember

3 varsomeInternalProperty=0//implicitly

internalclassmember

4 fileprivatefuncsomeFilePrivateMethod(){}//explicitly

file-privateclassmember

5 privatefuncsomePrivateMethod(){}//explicitly

privateclassmember

6 }

7

8 classSomeInternalClass{//implicitly

internalclass

9 varsomeInternalProperty=0//implicitly

internalclassmember

10 fileprivatefuncsomeFilePrivateMethod(){}//explicitly

file-privateclassmember

11 privatefuncsomePrivateMethod(){}//explicitly

privateclassmember

12 }

13

14 fileprivateclassSomeFilePrivateClass{//explicitly

Page 500: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

file-privateclass

15 funcsomeFilePrivateMethod(){}//implicitly

file-privateclassmember

16 privatefuncsomePrivateMethod(){}//explicitly

privateclassmember

17 }

18

19 privateclassSomePrivateClass{//explicitly

privateclass

20 funcsomePrivateMethod(){}//implicitly

privateclassmember

21 }

TupleTypesTheaccesslevelforatupletypeisthemostrestrictiveaccesslevelofalltypesusedinthattuple.Forexample,ifyoucomposeatuplefromtwodifferenttypes,onewithinternalaccessandonewithprivateaccess,theaccesslevelforthatcompoundtupletypewillbeprivate.

NOTE

Tupletypesdon’thaveastandalonedefinitioninthewaythatclasses,structures,enumerations,andfunctionsdo.Atupletype’saccesslevelisdeterminedautomaticallyfromthetypesthatmakeupthetupletype,andcan’tbespecifiedexplicitly.

FunctionTypesTheaccesslevelforafunctiontypeiscalculatedasthemostrestrictiveaccesslevelofthefunction’sparametertypesandreturntype.Youmustspecifytheaccesslevelexplicitlyaspartofthefunction’sdefinitionifthefunction’scalculatedaccessleveldoesn’tmatchthecontextualdefault.

Page 501: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheexamplebelowdefinesaglobalfunctioncalledsomeFunction(),withoutprovidingaspecificaccess-levelmodifierforthefunctionitself.Youmightexpectthisfunctiontohavethedefaultaccesslevelof“internal”,butthisisn’tthecase.Infact,someFunction()won’tcompileaswrittenbelow:

1 funcsomeFunction()->(SomeInternalClass,SomePrivateClass){

2 //functionimplementationgoeshere

3 }

Thefunction’sreturntypeisatupletypecomposedfromtwoofthecustomclassesdefinedaboveinCustomTypes.Oneoftheseclassesisdefinedasinternal,andtheotherisdefinedasprivate.Therefore,theoverallaccesslevelofthecompoundtupletypeisprivate(theminimumaccesslevelofthetuple’sconstituenttypes).

Becausethefunction’sreturntypeisprivate,youmustmarkthefunction’soverallaccesslevelwiththeprivatemodifierforthefunctiondeclarationtobevalid:

1 privatefuncsomeFunction()->(SomeInternalClass,

SomePrivateClass){

2 //functionimplementationgoeshere

3 }

It’snotvalidtomarkthedefinitionofsomeFunction()withthepublicorinternalmodifiers,ortousethedefaultsettingofinternal,becausepublicorinternalusersofthefunctionmightnothaveappropriateaccesstotheprivateclassusedinthefunction’sreturntype.

EnumerationTypesTheindividualcasesofanenumerationautomaticallyreceivethesameaccesslevelastheenumerationtheybelongto.Youcan’tspecifyadifferentaccesslevelforindividualenumerationcases.

Page 502: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Intheexamplebelow,theCompassPointenumerationhasanexplicitaccesslevelofpublic.Theenumerationcasesnorth,south,east,andwestthereforealsohaveanaccesslevelofpublic:

1 publicenumCompassPoint{

2 casenorth

3 casesouth

4 caseeast

5 casewest

6 }

RawValuesandAssociatedValues

Thetypesusedforanyrawvaluesorassociatedvaluesinanenumerationdefinitionmusthaveanaccesslevelatleastashighastheenumeration’saccesslevel.Forexample,youcan’tuseaprivatetypeastheraw-valuetypeofanenumerationwithaninternalaccesslevel.

NestedTypesTheaccesslevelofanestedtypeisthesameasitscontainingtype,unlessthecontainingtypeispublic.Nestedtypesdefinedwithinapublictypehaveanautomaticaccesslevelofinternal.Ifyouwantanestedtypewithinapublictypetobepubliclyavailable,youmustexplicitlydeclarethenestedtypeaspublic.

Subclassing

Youcansubclassanyclassthatcanbeaccessedinthecurrentaccesscontextandthat’sdefinedinthesamemoduleasthesubclass.Youcanalsosubclassanyopenclassthat’sdefinedinadifferentmodule.Asubclasscan’thaveahigheraccesslevelthanitssuperclass—forexample,youcan’twriteapublicsubclassofaninternalsuperclass.

Page 503: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Inaddition,forclassesthataredefinedinthesamemodule,youcanoverrideanyclassmember(method,property,initializer,orsubscript)that’svisibleinacertainaccesscontext.Forclassesthataredefinedinanothermodule,youcanoverrideanyopenclassmember.

Anoverridecanmakeaninheritedclassmembermoreaccessiblethanitssuperclassversion.Intheexamplebelow,classAisapublicclasswithafile-privatemethodcalledsomeMethod().ClassBisasubclassofA,withareducedaccesslevelof“internal”.Nonetheless,classBprovidesanoverrideofsomeMethod()withanaccesslevelof“internal”,whichishigherthantheoriginalimplementationofsomeMethod():

1 publicclassA{

2 fileprivatefuncsomeMethod(){}

3 }

4

5 internalclassB:A{

6 overrideinternalfuncsomeMethod(){}

7 }

It’sevenvalidforasubclassmembertocallasuperclassmemberthathasloweraccesspermissionsthanthesubclassmember,aslongasthecalltothesuperclass’smembertakesplacewithinanallowedaccesslevelcontext(thatis,withinthesamesourcefileasthesuperclassforafile-privatemembercall,orwithinthesamemoduleasthesuperclassforaninternalmembercall):

1 publicclassA{

2 fileprivatefuncsomeMethod(){}

3 }

4

5 internalclassB:A{

6 overrideinternalfuncsomeMethod(){

7 super.someMethod()

Page 504: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 }

9 }

BecausesuperclassAandsubclassBaredefinedinthesamesourcefile,it’svalidfortheBimplementationofsomeMethod()tocallsuper.someMethod().

Constants,Variables,Properties,andSubscripts

Aconstant,variable,orpropertycan’tbemorepublicthanitstype.It’snotvalidtowriteapublicpropertywithaprivatetype,forexample.Similarly,asubscriptcan’tbemorepublicthaneitheritsindextypeorreturntype.

Ifaconstant,variable,property,orsubscriptmakesuseofaprivatetype,theconstant,variable,property,orsubscriptmustalsobemarkedasprivate:

privatevarprivateInstance=SomePrivateClass()

GettersandSettersGettersandsettersforconstants,variables,properties,andsubscriptsautomaticallyreceivethesameaccesslevelastheconstant,variable,property,orsubscripttheybelongto.

Youcangiveasetteraloweraccesslevelthanitscorrespondinggetter,torestricttheread-writescopeofthatvariable,property,orsubscript.Youassignaloweraccesslevelbywritingfileprivate(set),private(set),orinternal(set)beforethevarorsubscriptintroducer.

NOTE

Thisruleappliestostoredpropertiesaswellascomputedproperties.Eventhoughyoudon’twriteanexplicitgetterandsetterforastoredproperty,Swiftstillsynthesizesanimplicitgetterandsetterforyoutoprovideaccesstothestoredproperty’sbackingstorage.Usefileprivate(set),private(set),andinternal(set)tochangetheaccesslevelofthissynthesizedsetterinexactlythesamewayasforanexplicitsetterinacomputedproperty.

Page 505: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheexamplebelowdefinesastructurecalledTrackedString,whichkeepstrackofthenumberoftimesastringpropertyismodified:

1 structTrackedString{

2 private(set)varnumberOfEdits=0

3 varvalue:String=""{

4 didSet{

5 numberOfEdits+=1

6 }

7 }

8 }

TheTrackedStringstructuredefinesastoredstringpropertycalledvalue,withaninitialvalueof""(anemptystring).ThestructurealsodefinesastoredintegerpropertycallednumberOfEdits,whichisusedtotrackthenumberoftimesthatvalueismodified.ThismodificationtrackingisimplementedwithadidSetpropertyobserveronthevalueproperty,whichincrementsnumberOfEditseverytimethevaluepropertyissettoanewvalue.

TheTrackedStringstructureandthevaluepropertydon’tprovideanexplicitaccess-levelmodifier,andsotheybothreceivethedefaultaccesslevelofinternal.However,theaccesslevelforthenumberOfEditspropertyismarkedwithaprivate(set)modifiertoindicatethattheproperty’sgetterstillhasthedefaultaccesslevelofinternal,butthepropertyissettableonlyfromwithincodethat’spartoftheTrackedStringstructure.ThisenablesTrackedStringtomodifythenumberOfEditspropertyinternally,buttopresentthepropertyasaread-onlypropertywhenit’susedoutsidethestructure’sdefinition.

IfyoucreateaTrackedStringinstanceandmodifyitsstringvalueafewtimes,youcanseethenumberOfEditspropertyvalueupdatetomatchthenumberofmodifications:

1 varstringToEdit=TrackedString()

2 stringToEdit.value="Thisstringwillbetracked."

3 stringToEdit.value+="Thiseditwillincrement

Page 506: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

numberOfEdits."

4 stringToEdit.value+="Sowillthisone."

5 print("Thenumberofeditsis\(stringToEdit.numberOfEdits)")

6 //Prints"Thenumberofeditsis3"

AlthoughyoucanquerythecurrentvalueofthenumberOfEditspropertyfromwithinanothersourcefile,youcan’tmodifythepropertyfromanothersourcefile.ThisrestrictionprotectstheimplementationdetailsoftheTrackedStringedit-trackingfunctionality,whilestillprovidingconvenientaccesstoanaspectofthatfunctionality.

Notethatyoucanassignanexplicitaccesslevelforbothagetterandasetterifrequired.TheexamplebelowshowsaversionoftheTrackedStringstructureinwhichthestructureisdefinedwithanexplicitaccesslevelofpublic.Thestructure’smembers(includingthenumberOfEditsproperty)thereforehaveaninternalaccesslevelbydefault.Youcanmakethestructure’snumberOfEditspropertygetterpublic,anditspropertysetterprivate,bycombiningthepublicandprivate(set)access-levelmodifiers:

1 publicstructTrackedString{

2 publicprivate(set)varnumberOfEdits=0

3 publicvarvalue:String=""{

4 didSet{

5 numberOfEdits+=1

6 }

7 }

8 publicinit(){}

9 }

Initializers

Custominitializerscanbeassignedanaccesslevellessthanorequaltothetype

Page 507: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thattheyinitialize.Theonlyexceptionisforrequiredinitializers(asdefinedinRequiredInitializers).Arequiredinitializermusthavethesameaccesslevelastheclassitbelongsto.

Aswithfunctionandmethodparameters,thetypesofaninitializer’sparameterscan’tbemoreprivatethantheinitializer’sownaccesslevel.

DefaultInitializersAsdescribedinDefaultInitializers,Swiftautomaticallyprovidesadefaultinitializerwithoutanyargumentsforanystructureorbaseclassthatprovidesdefaultvaluesforallofitspropertiesanddoesn’tprovideatleastoneinitializeritself.

Adefaultinitializerhasthesameaccesslevelasthetypeitinitializes,unlessthattypeisdefinedaspublic.Foratypethatisdefinedaspublic,thedefaultinitializerisconsideredinternal.Ifyouwantapublictypetobeinitializablewithano-argumentinitializerwhenusedinanothermodule,youmustexplicitlyprovideapublicno-argumentinitializeryourselfaspartofthetype’sdefinition.

DefaultMemberwiseInitializersforStructureTypesThedefaultmemberwiseinitializerforastructuretypeisconsideredprivateifanyofthestructure’sstoredpropertiesareprivate.Likewise,ifanyofthestructure’sstoredpropertiesarefileprivate,theinitializerisfileprivate.Otherwise,theinitializerhasanaccesslevelofinternal.

Aswiththedefaultinitializerabove,ifyouwantapublicstructuretypetobeinitializablewithamemberwiseinitializerwhenusedinanothermodule,youmustprovideapublicmemberwiseinitializeryourselfaspartofthetype’sdefinition.

Protocols

Page 508: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Ifyouwanttoassignanexplicitaccessleveltoaprotocoltype,dosoatthepointthatyoudefinetheprotocol.Thisenablesyoutocreateprotocolsthatcanonlybeadoptedwithinacertainaccesscontext.

Theaccesslevelofeachrequirementwithinaprotocoldefinitionisautomaticallysettothesameaccesslevelastheprotocol.Youcan’tsetaprotocolrequirementtoadifferentaccesslevelthantheprotocolitsupports.Thisensuresthatalloftheprotocol’srequirementswillbevisibleonanytypethatadoptstheprotocol.

NOTE

Ifyoudefineapublicprotocol,theprotocol’srequirementsrequireapublicaccesslevelforthoserequirementswhenthey’reimplemented.Thisbehaviorisdifferentfromothertypes,whereapublictypedefinitionimpliesanaccesslevelofinternalforthetype’smembers.

ProtocolInheritanceIfyoudefineanewprotocolthatinheritsfromanexistingprotocol,thenewprotocolcanhaveatmostthesameaccesslevelastheprotocolitinheritsfrom.Forexample,youcan’twriteapublicprotocolthatinheritsfromaninternalprotocol.

ProtocolConformanceAtypecanconformtoaprotocolwithaloweraccesslevelthanthetypeitself.Forexample,youcandefineapublictypethatcanbeusedinothermodules,butwhoseconformancetoaninternalprotocolcanonlybeusedwithintheinternalprotocol’sdefiningmodule.

Thecontextinwhichatypeconformstoaparticularprotocolistheminimumofthetype’saccesslevelandtheprotocol’saccesslevel.Forexample,ifatypeispublic,butaprotocolitconformstoisinternal,thetype’sconformancetothatprotocolisalsointernal.

Whenyouwriteorextendatypetoconformtoaprotocol,youmustensurethat

Page 509: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thetype’simplementationofeachprotocolrequirementhasatleastthesameaccesslevelasthetype’sconformancetothatprotocol.Forexample,ifapublictypeconformstoaninternalprotocol,thetype’simplementationofeachprotocolrequirementmustbeatleastinternal.

NOTE

InSwift,asinObjective-C,protocolconformanceisglobal—itisn’tpossibleforatypetoconformtoaprotocolintwodifferentwayswithinthesameprogram.

Extensions

Youcanextendaclass,structure,orenumerationinanyaccesscontextinwhichtheclass,structure,orenumerationisavailable.Anytypemembersaddedinanextensionhavethesamedefaultaccesslevelastypemembersdeclaredintheoriginaltypebeingextended.Ifyouextendapublicorinternaltype,anynewtypemembersyouaddhaveadefaultaccesslevelofinternal.Ifyouextendafile-privatetype,anynewtypemembersyouaddhaveadefaultaccessleveloffileprivate.Ifyouextendaprivatetype,anynewtypemembersyouaddhaveadefaultaccesslevelofprivate.

Alternatively,youcanmarkanextensionwithanexplicitaccess-levelmodifier(forexample,private)tosetanewdefaultaccesslevelforallmembersdefinedwithintheextension.Thisnewdefaultcanstillbeoverriddenwithintheextensionforindividualtypemembers.

Youcan’tprovideanexplicitaccess-levelmodifierforanextensionifyou’reusingthatextensiontoaddprotocolconformance.Instead,theprotocol’sownaccesslevelisusedtoprovidethedefaultaccesslevelforeachprotocolrequirementimplementationwithintheextension.

PrivateMembersinExtensionsExtensionsthatareinthesamefileastheclass,structure,orenumerationthattheyextendbehaveasifthecodeintheextensionhadbeenwrittenaspartofthe

Page 510: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

originaltype’sdeclaration.Asaresult,youcan:

Declareaprivatememberintheoriginaldeclaration,andaccessthatmemberfromextensionsinthesamefile.

Declareaprivatememberinoneextension,andaccessthatmemberfromanotherextensioninthesamefile.

Declareaprivatememberinanextension,andaccessthatmemberfromtheoriginaldeclarationinthesamefile.

Thisbehaviormeansyoucanuseextensionsinthesamewaytoorganizeyourcode,whetherornotyourtypeshaveprivateentities.Forexample,giventhefollowingsimpleprotocol:

1 protocolSomeProtocol{

2 funcdoSomething()

3 }

Youcanuseanextensiontoaddprotocolconformance,likethis:

1 structSomeStruct{

2 privatevarprivateVariable=12

3 }

4

5 extensionSomeStruct:SomeProtocol{

6 funcdoSomething(){

7 print(privateVariable)

8 }

9 }

Generics

Page 511: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theaccesslevelforagenerictypeorgenericfunctionistheminimumoftheaccesslevelofthegenerictypeorfunctionitselfandtheaccesslevelofanytypeconstraintsonitstypeparameters.

TypeAliases

Anytypealiasesyoudefinearetreatedasdistincttypesforthepurposesofaccesscontrol.Atypealiascanhaveanaccesslevellessthanorequaltotheaccesslevelofthetypeitaliases.Forexample,aprivatetypealiascanaliasaprivate,file-private,internal,public,oropentype,butapublictypealiascan’taliasaninternal,file-private,orprivatetype.

NOTE

Thisrulealsoappliestotypealiasesforassociatedtypesusedtosatisfyprotocolconformances.

Page 512: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AdvancedOperators

InadditiontotheoperatorsdescribedinBasicOperators,Swiftprovidesseveraladvancedoperatorsthatperformmorecomplexvaluemanipulation.TheseincludeallofthebitwiseandbitshiftingoperatorsyouwillbefamiliarwithfromCandObjective-C.

UnlikearithmeticoperatorsinC,arithmeticoperatorsinSwiftdonotoverflowbydefault.Overflowbehavioristrappedandreportedasanerror.Tooptintooverflowbehavior,useSwift’ssecondsetofarithmeticoperatorsthatoverflowbydefault,suchastheoverflowadditionoperator(&+).Alloftheseoverflowoperatorsbeginwithanampersand(&).

Whenyoudefineyourownstructures,classes,andenumerations,itcanbeusefultoprovideyourownimplementationsofthestandardSwiftoperatorsforthesecustomtypes.Swiftmakesiteasytoprovidetailoredimplementationsoftheseoperatorsandtodetermineexactlywhattheirbehaviorshouldbeforeachtypeyoucreate.

You’renotlimitedtothepredefinedoperators.Swiftgivesyouthefreedomtodefineyourowncustominfix,prefix,postfix,andassignmentoperators,withcustomprecedenceandassociativityvalues.Theseoperatorscanbeusedandadoptedinyourcodelikeanyofthepredefinedoperators,andyoucanevenextendexistingtypestosupportthecustomoperatorsyoudefine.

BitwiseOperators

Bitwiseoperatorsenableyoutomanipulatetheindividualrawdatabitswithinadatastructure.Theyareoftenusedinlow-levelprogramming,suchasgraphicsprogramminganddevicedrivercreation.Bitwiseoperatorscanalsobeusefulwhenyouworkwithrawdatafromexternalsources,suchasencodinganddecodingdataforcommunicationoveracustomprotocol.

SwiftsupportsallofthebitwiseoperatorsfoundinC,asdescribedbelow.

Page 513: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

BitwiseNOTOperatorThebitwiseNOToperator(~)invertsallbitsinanumber:

ThebitwiseNOToperatorisaprefixoperator,andappearsimmediatelybeforethevalueitoperateson,withoutanywhitespace:

1 letinitialBits:UInt8=0b00001111

2 letinvertedBits=~initialBits//equals11110000

UInt8integershaveeightbitsandcanstoreanyvaluebetween0and255.ThisexampleinitializesaUInt8integerwiththebinaryvalue00001111,whichhasitsfirstfourbitssetto0,anditssecondfourbitssetto1.Thisisequivalenttoadecimalvalueof15.

ThebitwiseNOToperatoristhenusedtocreateanewconstantcalledinvertedBits,whichisequaltoinitialBits,butwithallofthebitsinverted.Zerosbecomeones,andonesbecomezeros.ThevalueofinvertedBitsis11110000,whichisequaltoanunsigneddecimalvalueof240.

BitwiseANDOperatorThebitwiseANDoperator(&)combinesthebitsoftwonumbers.Itreturnsanewnumberwhosebitsaresetto1onlyifthebitswereequalto1inbothinputnumbers:

Page 514: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Intheexamplebelow,thevaluesoffirstSixBitsandlastSixBitsbothhavefourmiddlebitsequalto1.ThebitwiseANDoperatorcombinesthemtomakethenumber00111100,whichisequaltoanunsigneddecimalvalueof60:

1 letfirstSixBits:UInt8=0b11111100

2 letlastSixBits:UInt8=0b00111111

3 letmiddleFourBits=firstSixBits&lastSixBits//equals

00111100

BitwiseOROperatorThebitwiseORoperator(|)comparesthebitsoftwonumbers.Theoperatorreturnsanewnumberwhosebitsaresetto1ifthebitsareequalto1ineitherinputnumber:

Intheexamplebelow,thevaluesofsomeBitsandmoreBitshavedifferentbitsset

Page 515: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

to1.ThebitwiseORoperatorcombinesthemtomakethenumber11111110,whichequalsanunsigneddecimalof254:

1 letsomeBits:UInt8=0b10110010

2 letmoreBits:UInt8=0b01011110

3 letcombinedbits=someBits|moreBits//equals11111110

BitwiseXOROperatorThebitwiseXORoperator,or“exclusiveORoperator”(^),comparesthebitsoftwonumbers.Theoperatorreturnsanewnumberwhosebitsaresetto1wheretheinputbitsaredifferentandaresetto0wheretheinputbitsarethesame:

Intheexamplebelow,thevaluesoffirstBitsandotherBitseachhaveabitsetto1inalocationthattheotherdoesnot.ThebitwiseXORoperatorsetsbothofthesebitsto1initsoutputvalue.AlloftheotherbitsinfirstBitsandotherBitsmatchandaresetto0intheoutputvalue:

1 letfirstBits:UInt8=0b00010100

2 letotherBits:UInt8=0b00000101

3 letoutputBits=firstBits^otherBits//equals00010001

BitwiseLeftandRightShiftOperators

Page 516: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thebitwiseleftshiftoperator(<<)andbitwiserightshiftoperator(>>)moveallbitsinanumbertotheleftortherightbyacertainnumberofplaces,accordingtotherulesdefinedbelow.

Bitwiseleftandrightshiftshavetheeffectofmultiplyingordividinganintegerbyafactoroftwo.Shiftinganinteger’sbitstotheleftbyonepositiondoublesitsvalue,whereasshiftingittotherightbyonepositionhalvesitsvalue.

ShiftingBehaviorforUnsignedIntegers

Thebit-shiftingbehaviorforunsignedintegersisasfollows:

1. Existingbitsaremovedtotheleftorrightbytherequestednumberofplaces.

2. Anybitsthataremovedbeyondtheboundsoftheinteger’sstoragearediscarded.

3. Zerosareinsertedinthespacesleftbehindaftertheoriginalbitsaremovedtotheleftorright.

Thisapproachisknownasalogicalshift.

Theillustrationbelowshowstheresultsof11111111<<1(whichis11111111shiftedtotheleftby1place),and11111111>>1(whichis11111111shiftedtotherightby1place).Bluenumbersareshifted,graynumbersarediscarded,andorangezerosareinserted:

Here’showbitshiftinglooksinSwiftcode:

1 letshiftBits:UInt8=4//00000100inbinary

Page 517: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 shiftBits<<1//00001000

3 shiftBits<<2//00010000

4 shiftBits<<5//10000000

5 shiftBits<<6//00000000

6 shiftBits>>2//00000001

Youcanusebitshiftingtoencodeanddecodevalueswithinotherdatatypes:

1 letpink:UInt32=0xCC6699

2 letredComponent=(pink&0xFF0000)>>16//redComponent

is0xCC,or204

3 letgreenComponent=(pink&0x00FF00)>>8//greenComponent

is0x66,or102

4 letblueComponent=pink&0x0000FF//blueComponent

is0x99,or153

ThisexampleusesaUInt32constantcalledpinktostoreaCascadingStyleSheetscolorvalueforthecolorpink.TheCSScolorvalue#CC6699iswrittenas0xCC6699inSwift’shexadecimalnumberrepresentation.Thiscoloristhendecomposedintoitsred(CC),green(66),andblue(99)componentsbythebitwiseANDoperator(&)andthebitwiserightshiftoperator(>>).

TheredcomponentisobtainedbyperformingabitwiseANDbetweenthenumbers0xCC6699and0xFF0000.Thezerosin0xFF0000effectively“mask”thesecondandthirdbytesof0xCC6699,causingthe6699tobeignoredandleaving0xCC0000astheresult.

Thisnumberisthenshifted16placestotheright(>>16).Eachpairofcharactersinahexadecimalnumberuses8bits,soamove16placestotherightwillconvert0xCC0000into0x0000CC.Thisisthesameas0xCC,whichhasadecimalvalueof204.

Similarly,thegreencomponentisobtainedbyperformingabitwiseANDbetweenthenumbers0xCC6699and0x00FF00,whichgivesanoutputvalueof0x006600.Thisoutputvalueisthenshiftedeightplacestotheright,givinga

Page 518: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

valueof0x66,whichhasadecimalvalueof102.

Finally,thebluecomponentisobtainedbyperformingabitwiseANDbetweenthenumbers0xCC6699and0x0000FF,whichgivesanoutputvalueof0x000099.There’snoneedtoshiftthistotheright,as0x000099alreadyequals0x99,whichhasadecimalvalueof153.

ShiftingBehaviorforSignedIntegers

Theshiftingbehaviorismorecomplexforsignedintegersthanforunsignedintegers,becauseofthewaysignedintegersarerepresentedinbinary.(Theexamplesbelowarebasedon8-bitsignedintegersforsimplicity,butthesameprinciplesapplyforsignedintegersofanysize.)

Signedintegersusetheirfirstbit(knownasthesignbit)toindicatewhethertheintegerispositiveornegative.Asignbitof0meanspositive,andasignbitof1meansnegative.

Theremainingbits(knownasthevaluebits)storetheactualvalue.Positivenumbersarestoredinexactlythesamewayasforunsignedintegers,countingupwardsfrom0.Here’showthebitsinsideanInt8lookforthenumber4:

Thesignbitis0(meaning“positive”),andthesevenvaluebitsarejustthenumber4,writteninbinarynotation.

Negativenumbers,however,arestoreddifferently.Theyarestoredbysubtractingtheirabsolutevaluefrom2tothepowerofn,wherenisthenumberofvaluebits.Aneight-bitnumberhassevenvaluebits,sothismeans2tothepowerof7,or128.

Here’showthebitsinsideanInt8lookforthenumber-4:

Page 519: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thistime,thesignbitis1(meaning“negative”),andthesevenvaluebitshaveabinaryvalueof124(whichis128-4):

Thisencodingfornegativenumbersisknownasatwo’scomplementrepresentation.Itmayseemanunusualwaytorepresentnegativenumbers,butithasseveraladvantages.

First,youcanadd-1to-4,simplybyperformingastandardbinaryadditionofalleightbits(includingthesignbit),anddiscardinganythingthatdoesn’tfitintheeightbitsonceyou’redone:

Second,thetwo’scomplementrepresentationalsoletsyoushiftthebitsofnegativenumberstotheleftandrightlikepositivenumbers,andstillendupdoublingthemforeveryshiftyoumaketotheleft,orhalvingthemforeveryshiftyoumaketotheright.Toachievethis,anextraruleisusedwhensignedintegersareshiftedtotheright:Whenyoushiftsignedintegerstotheright,applythesamerulesasforunsignedintegers,butfillanyemptybitsontheleftwiththesignbit,ratherthanwithazero.

Page 520: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thisactionensuresthatsignedintegershavethesamesignaftertheyareshiftedtotheright,andisknownasanarithmeticshift.

Becauseofthespecialwaythatpositiveandnegativenumbersarestored,shiftingeitherofthemtotherightmovesthemclosertozero.Keepingthesignbitthesameduringthisshiftmeansthatnegativeintegersremainnegativeastheirvaluemovesclosertozero.

OverflowOperators

Ifyoutrytoinsertanumberintoanintegerconstantorvariablethatcannotholdthatvalue,bydefaultSwiftreportsanerrorratherthanallowinganinvalidvaluetobecreated.Thisbehaviorgivesextrasafetywhenyouworkwithnumbersthataretoolargeortoosmall.

Forexample,theInt16integertypecanholdanysignedintegerbetween-32768and32767.TryingtosetanInt16constantorvariabletoanumberoutsideofthisrangecausesanerror:

1 varpotentialOverflow=Int16.max

2 //potentialOverflowequals32767,whichisthemaximumvalue

anInt16canhold

3 potentialOverflow+=1

4 //thiscausesanerror

Providingerrorhandlingwhenvaluesgettoolargeortoosmallgivesyoumuchmoreflexibilitywhencodingforboundaryvalueconditions.

Page 521: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

However,whenyouspecificallywantanoverflowconditiontotruncatethenumberofavailablebits,youcanoptintothisbehaviorratherthantriggeringanerror.Swiftprovidesthreearithmeticoverflowoperatorsthatoptintotheoverflowbehaviorforintegercalculations.Theseoperatorsallbeginwithanampersand(&):

Overflowaddition(&+)

Overflowsubtraction(&-)

Overflowmultiplication(&*)

ValueOverflowNumberscanoverflowinboththepositiveandnegativedirection.

Here’sanexampleofwhathappenswhenanunsignedintegerisallowedtooverflowinthepositivedirection,usingtheoverflowadditionoperator(&+):

1 varunsignedOverflow=UInt8.max

2 //unsignedOverflowequals255,whichisthemaximumvaluea

UInt8canhold

3 unsignedOverflow=unsignedOverflow&+1

4 //unsignedOverflowisnowequalto0

ThevariableunsignedOverflowisinitializedwiththemaximumvalueaUInt8canhold(255,or11111111inbinary).Itisthenincrementedby1usingtheoverflowadditionoperator(&+).ThispushesitsbinaryrepresentationjustoverthesizethataUInt8canhold,causingittooverflowbeyonditsbounds,asshowninthediagrambelow.ThevaluethatremainswithintheboundsoftheUInt8aftertheoverflowadditionis00000000,orzero.

Page 522: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Somethingsimilarhappenswhenanunsignedintegerisallowedtooverflowinthenegativedirection.Here’sanexampleusingtheoverflowsubtractionoperator(&-):

1 varunsignedOverflow=UInt8.min

2 //unsignedOverflowequals0,whichistheminimumvaluea

UInt8canhold

3 unsignedOverflow=unsignedOverflow&-1

4 //unsignedOverflowisnowequalto255

TheminimumvaluethataUInt8canholdiszero,or00000000inbinary.Ifyousubtract1from00000000usingtheoverflowsubtractionoperator(&-),thenumberwilloverflowandwraparoundto11111111,or255indecimal.

Overflowalsooccursforsignedintegers.Alladditionandsubtractionforsignedintegersisperformedinbitwisefashion,withthesignbitincludedaspartofthenumbersbeingaddedorsubtracted,asdescribedinBitwiseLeftandRightShiftOperators.

1 varsignedOverflow=Int8.min

Page 523: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 //signedOverflowequals-128,whichistheminimumvaluean

Int8canhold

3 signedOverflow=signedOverflow&-1

4 //signedOverflowisnowequalto127

TheminimumvaluethatanInt8canholdis-128,or10000000inbinary.Subtracting1fromthisbinarynumberwiththeoverflowoperatorgivesabinaryvalueof01111111,whichtogglesthesignbitandgivespositive127,themaximumpositivevaluethatanInt8canhold.

Forbothsignedandunsignedintegers,overflowinthepositivedirectionwrapsaroundfromthemaximumvalidintegervaluebacktotheminimum,andoverflowinthenegativedirectionwrapsaroundfromtheminimumvaluetothemaximum.

PrecedenceandAssociativity

Operatorprecedencegivessomeoperatorshigherprioritythanothers;theseoperatorsareappliedfirst.

Operatorassociativitydefineshowoperatorsofthesameprecedencearegroupedtogether—eithergroupedfromtheleft,orgroupedfromtheright.Thinkofitasmeaning“theyassociatewiththeexpressiontotheirleft,”or“theyassociatewiththeexpressiontotheirright.”

Page 524: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Itisimportanttoconsidereachoperator’sprecedenceandassociativitywhenworkingouttheorderinwhichacompoundexpressionwillbecalculated.Forexample,operatorprecedenceexplainswhythefollowingexpressionequals17.

1 2+3%4*5

2 //thisequals17

Ifyoureadstrictlyfromlefttoright,youmightexpecttheexpressiontobecalculatedasfollows:

2plus3equals5

5remainder4equals1

1times5equals5

However,theactualansweris17,not5.Higher-precedenceoperatorsareevaluatedbeforelower-precedenceones.InSwift,asinC,theremainderoperator(%)andthemultiplicationoperator(*)haveahigherprecedencethantheadditionoperator(+).Asaresult,theyarebothevaluatedbeforetheadditionisconsidered.

However,remainderandmultiplicationhavethesameprecedenceaseachother.Toworkouttheexactevaluationordertouse,youalsoneedtoconsidertheirassociativity.Remainderandmultiplicationbothassociatewiththeexpressiontotheirleft.Thinkofthisasaddingimplicitparenthesesaroundthesepartsoftheexpression,startingfromtheirleft:

2+((3%4)*5)

(3%4)is3,sothisisequivalentto:

2+(3*5)

(3*5)is15,sothisisequivalentto:

2+15

Page 525: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thiscalculationyieldsthefinalanswerof17.

ForinformationabouttheoperatorsprovidedbytheSwiftstandardlibrary,includingacompletelistoftheoperatorprecedencegroupsandassociativitysettings,seeOperatorDeclarations.

NOTE

Swift’soperatorprecedencesandassociativityrulesaresimplerandmorepredictablethanthosefoundinCandObjective-C.However,thismeansthattheyarenotexactlythesameasinC-basedlanguages.BecarefultoensurethatoperatorinteractionsstillbehaveinthewayyouintendwhenportingexistingcodetoSwift.

OperatorMethods

Classesandstructurescanprovidetheirownimplementationsofexistingoperators.Thisisknownasoverloadingtheexistingoperators.

Theexamplebelowshowshowtoimplementthearithmeticadditionoperator(+)foracustomstructure.Thearithmeticadditionoperatorisabinaryoperatorbecauseitoperatesontwotargetsandissaidtobeinfixbecauseitappearsinbetweenthosetwotargets.

TheexampledefinesaVector2Dstructureforatwo-dimensionalpositionvector(x,y),followedbyadefinitionofanoperatormethodtoaddtogetherinstancesoftheVector2Dstructure:

1 structVector2D{

2 varx=0.0,y=0.0

3 }

4

5 extensionVector2D{

6 staticfunc+(left:Vector2D,right:Vector2D)->Vector2D

{

Page 526: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

7 returnVector2D(x:left.x+right.x,y:left.y+

right.y)

8 }

9 }

TheoperatormethodisdefinedasatypemethodonVector2D,withamethodnamethatmatchestheoperatortobeoverloaded(+).Becauseadditionisn’tpartoftheessentialbehaviorforavector,thetypemethodisdefinedinanextensionofVector2DratherthaninthemainstructuredeclarationofVector2D.Becausethearithmeticadditionoperatorisabinaryoperator,thisoperatormethodtakestwoinputparametersoftypeVector2Dandreturnsasingleoutputvalue,alsooftypeVector2D.

Inthisimplementation,theinputparametersarenamedleftandrighttorepresenttheVector2Dinstancesthatwillbeontheleftsideandrightsideofthe+operator.ThemethodreturnsanewVector2Dinstance,whosexandypropertiesareinitializedwiththesumofthexandypropertiesfromthetwoVector2Dinstancesthatareaddedtogether.

ThetypemethodcanbeusedasaninfixoperatorbetweenexistingVector2Dinstances:

1 letvector=Vector2D(x:3.0,y:1.0)

2 letanotherVector=Vector2D(x:2.0,y:4.0)

3 letcombinedVector=vector+anotherVector

4 //combinedVectorisaVector2Dinstancewithvaluesof(5.0,

5.0)

Thisexampleaddstogetherthevectors(3.0,1.0)and(2.0,4.0)tomakethevector(5.0,5.0),asillustratedbelow.

Page 527: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

PrefixandPostfixOperatorsTheexampleshownabovedemonstratesacustomimplementationofabinaryinfixoperator.Classesandstructurescanalsoprovideimplementationsofthestandardunaryoperators.Unaryoperatorsoperateonasingletarget.Theyareprefixiftheyprecedetheirtarget(suchas-a)andpostfixoperatorsiftheyfollowtheirtarget(suchasb!).

Youimplementaprefixorpostfixunaryoperatorbywritingtheprefixorpostfixmodifierbeforethefunckeywordwhendeclaringtheoperatormethod:

1 extensionVector2D{

2 staticprefixfunc-(vector:Vector2D)->Vector2D{

3 returnVector2D(x:-vector.x,y:-vector.y)

4 }

5 }

Theexampleaboveimplementstheunaryminusoperator(-a)forVector2D

Page 528: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

instances.Theunaryminusoperatorisaprefixoperator,andsothismethodhastobequalifiedwiththeprefixmodifier.

Forsimplenumericvalues,theunaryminusoperatorconvertspositivenumbersintotheirnegativeequivalentandviceversa.ThecorrespondingimplementationforVector2Dinstancesperformsthisoperationonboththexandyproperties:

1 letpositive=Vector2D(x:3.0,y:4.0)

2 letnegative=-positive

3 //negativeisaVector2Dinstancewithvaluesof(-3.0,-4.0)

4 letalsoPositive=-negative

5 //alsoPositiveisaVector2Dinstancewithvaluesof(3.0,

4.0)

CompoundAssignmentOperatorsCompoundassignmentoperatorscombineassignment(=)withanotheroperation.Forexample,theadditionassignmentoperator(+=)combinesadditionandassignmentintoasingleoperation.Youmarkacompoundassignmentoperator’sleftinputparametertypeasinout,becausetheparameter’svaluewillbemodifieddirectlyfromwithintheoperatormethod.

TheexamplebelowimplementsanadditionassignmentoperatormethodforVector2Dinstances:

1 extensionVector2D{

2 staticfunc+=(left:inoutVector2D,right:Vector2D){

3 left=left+right

4 }

5 }

Becauseanadditionoperatorwasdefinedearlier,youdon’tneedtoreimplementtheadditionprocesshere.Instead,theadditionassignmentoperatormethodtakesadvantageoftheexistingadditionoperatormethod,andusesittosettheleft

Page 529: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

valuetobetheleftvalueplustherightvalue:

1 varoriginal=Vector2D(x:1.0,y:2.0)

2 letvectorToAdd=Vector2D(x:3.0,y:4.0)

3 original+=vectorToAdd

4 //originalnowhasvaluesof(4.0,6.0)

NOTE

Itisn’tpossibletooverloadthedefaultassignmentoperator(=).Onlythecompoundassignmentoperatorscanbeoverloaded.Similarly,theternaryconditionaloperator(a?b:c)can’tbeoverloaded.

EquivalenceOperatorsBydefault,customclassesandstructuresdon’thaveanimplementationoftheequivalenceoperators,knownastheequaltooperator(==)andnotequaltooperator(!=).Youusuallyimplementthe==operator,andusethestandardlibrary’sdefaultimplementationofthe!=operatorthatnegatestheresultofthe==operator.Therearetwowaystoimplementthe==operator:Youcanimplementityourself,orformanytypes,youcanaskSwifttosynthesizeanimplementationforyou.Inbothcases,youaddconformancetothestandardlibrary’sEquatableprotocol.

Youprovideanimplementationofthe==operatorinthesamewayasyouimplementotherinfixoperators:

1 extensionVector2D:Equatable{

2 staticfunc==(left:Vector2D,right:Vector2D)->Bool{

3 return(left.x==right.x)&&(left.y==right.y)

4 }

5 }

Theexampleaboveimplementsan==operatortocheckwhethertwoVector2Dinstanceshaveequivalentvalues.InthecontextofVector2D,itmakessenseto

Page 530: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

consider“equal”asmeaning“bothinstanceshavethesamexvaluesandyvalues”,andsothisisthelogicusedbytheoperatorimplementation.

YoucannowusethisoperatortocheckwhethertwoVector2Dinstancesareequivalent:

1 lettwoThree=Vector2D(x:2.0,y:3.0)

2 letanotherTwoThree=Vector2D(x:2.0,y:3.0)

3 iftwoThree==anotherTwoThree{

4 print("Thesetwovectorsareequivalent.")

5 }

6 //Prints"Thesetwovectorsareequivalent."

Inmanysimplecases,youcanaskSwifttoprovidesynthesizedimplementationsoftheequivalenceoperatorsforyou.Swiftprovidessynthesizedimplementationsforthefollowingkindsofcustomtypes:

StructuresthathaveonlystoredpropertiesthatconformtotheEquatableprotocol

EnumerationsthathaveonlyassociatedtypesthatconformtotheEquatableprotocol

Enumerationsthathavenoassociatedtypes

Toreceiveasynthesizedimplementationof==,declareEquatableconformanceinthefilethatcontainstheoriginaldeclaration,withoutimplementingan==operatoryourself.

TheexamplebelowdefinesaVector3Dstructureforathree-dimensionalpositionvector(x,y,z),similartotheVector2Dstructure.Becausethex,y,andzpropertiesareallofanEquatabletype,Vector3Dreceivessynthesizedimplementationsoftheequivalenceoperators.

1 structVector3D:Equatable{

2 varx=0.0,y=0.0,z=0.0

Page 531: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 }

4

5 lettwoThreeFour=Vector3D(x:2.0,y:3.0,z:4.0)

6 letanotherTwoThreeFour=Vector3D(x:2.0,y:3.0,z:4.0)

7 iftwoThreeFour==anotherTwoThreeFour{

8 print("Thesetwovectorsarealsoequivalent.")

9 }

10 //Prints"Thesetwovectorsarealsoequivalent."

CustomOperators

YoucandeclareandimplementyourowncustomoperatorsinadditiontothestandardoperatorsprovidedbySwift.Foralistofcharactersthatcanbeusedtodefinecustomoperators,seeOperators.

Newoperatorsaredeclaredatagloballevelusingtheoperatorkeyword,andaremarkedwiththeprefix,infixorpostfixmodifiers:

prefixoperator+++

Theexampleabovedefinesanewprefixoperatorcalled+++.ThisoperatordoesnothaveanexistingmeaninginSwift,andsoitisgivenitsowncustommeaningbelowinthespecificcontextofworkingwithVector2Dinstances.Forthepurposesofthisexample,+++istreatedasanew“prefixdoubling”operator.ItdoublesthexandyvaluesofaVector2Dinstance,byaddingthevectortoitselfwiththeadditionassignmentoperatordefinedearlier.Toimplementthe+++operator,youaddatypemethodcalled+++toVector2Dasfollows:

1 extensionVector2D{

2 staticprefixfunc+++(vector:inoutVector2D)->Vector2D

{

3 vector+=vector

Page 532: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

4 returnvector

5 }

6 }

7

8 vartoBeDoubled=Vector2D(x:1.0,y:4.0)

9 letafterDoubling=+++toBeDoubled

10 //toBeDoublednowhasvaluesof(2.0,8.0)

11 //afterDoublingalsohasvaluesof(2.0,8.0)

PrecedenceforCustomInfixOperatorsCustominfixoperatorseachbelongtoaprecedencegroup.Aprecedencegroupspecifiesanoperator’sprecedencerelativetootherinfixoperators,aswellastheoperator’sassociativity.SeePrecedenceandAssociativityforanexplanationofhowthesecharacteristicsaffectaninfixoperator’sinteractionwithotherinfixoperators.

Acustominfixoperatorthatisnotexplicitlyplacedintoaprecedencegroupisgivenadefaultprecedencegroupwithaprecedenceimmediatelyhigherthantheprecedenceoftheternaryconditionaloperator.

Thefollowingexampledefinesanewcustominfixoperatorcalled+-,whichbelongstotheprecedencegroupAdditionPrecedence:

1 infixoperator+-:AdditionPrecedence

2 extensionVector2D{

3 staticfunc+-(left:Vector2D,right:Vector2D)->

Vector2D{

4 returnVector2D(x:left.x+right.x,y:left.y-

right.y)

5 }

6 }

Page 533: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

7 letfirstVector=Vector2D(x:1.0,y:2.0)

8 letsecondVector=Vector2D(x:3.0,y:4.0)

9 letplusMinusVector=firstVector+-secondVector

10 //plusMinusVectorisaVector2Dinstancewithvaluesof(4.0,

-2.0)

Thisoperatoraddstogetherthexvaluesoftwovectors,andsubtractstheyvalueofthesecondvectorfromthefirst.Becauseitisinessencean“additive”operator,ithasbeengiventhesameprecedencegroupasadditiveinfixoperatorssuchas+and-.ForinformationabouttheoperatorsprovidedbytheSwiftstandardlibrary,includingacompletelistoftheoperatorprecedencegroupsandassociativitysettings,seeOperatorDeclarations.Formoreinformationaboutprecedencegroupsandtoseethesyntaxfordefiningyourownoperatorsandprecedencegroups,seeOperatorDeclaration.

NOTE

Youdonotspecifyaprecedencewhendefiningaprefixorpostfixoperator.However,ifyouapplybothaprefixandapostfixoperatortothesameoperand,thepostfixoperatorisappliedfirst.

Page 534: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

LanguageReference

Page 535: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AbouttheLanguageReference

ThispartofthebookdescribestheformalgrammaroftheSwiftprogramminglanguage.Thegrammardescribedhereisintendedtohelpyouunderstandthelanguageinmoredetail,ratherthantoallowyoutodirectlyimplementaparserorcompiler.

TheSwiftlanguageisrelativelysmall,becausemanycommontypes,functions,andoperatorsthatappearvirtuallyeverywhereinSwiftcodeareactuallydefinedintheSwiftstandardlibrary.Althoughthesetypes,functions,andoperatorsarenotpartoftheSwiftlanguageitself,theyareusedextensivelyinthediscussionsandcodeexamplesinthispartofthebook.

HowtoReadtheGrammar

ThenotationusedtodescribetheformalgrammaroftheSwiftprogramminglanguagefollowsafewconventions:

Anarrow(→)isusedtomarkgrammarproductionsandcanbereadas“canconsistof.”

Syntacticcategoriesareindicatedbyitalictextandappearonbothsidesofagrammarproductionrule.

Literalwordsandpunctuationareindicatedbyboldfaceconstantwidthtextandappearonlyontheright-handsideofagrammarproductionrule.

Alternativegrammarproductionsareseparatedbyverticalbars(|).Whenalternativeproductionsaretoolongtoreadeasily,theyarebrokenintomultiplegrammarproductionrulesonnewlines.

Inafewcases,regularfonttextisusedtodescribetheright-handsideofagrammarproductionrule.

Page 536: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Optionalsyntacticcategoriesandliteralsaremarkedbyatrailingsubscript,opt.

Asanexample,thegrammarofagetter-setterblockisdefinedasfollows:

GRAMMAR OF AGETTER -SETTER BLOCK

getter-setter-block → { getter-clause setter-clause opt } | { setter-clause getter-clause }

Thisdefinitionindicatesthatagetter-setterblockcanconsistofagetterclausefollowedbyanoptionalsetterclause,enclosedinbraces,orasetterclausefollowedbyagetterclause,enclosedinbraces.Thegrammarproductionaboveisequivalenttothefollowingtwoproductions,wherethealternativesarespelledoutexplicitly:

GRAMMAR OF AGETTER -SETTER BLOCK

getter-setter-block → { getter-clause setter-clause opt }getter-setter-block → { setter-clause getter-clause }

Page 537: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

LexicalStructure

ThelexicalstructureofSwiftdescribeswhatsequenceofcharactersformvalidtokensofthelanguage.Thesevalidtokensformthelowest-levelbuildingblocksofthelanguageandareusedtodescribetherestofthelanguageinsubsequentchapters.Atokenconsistsofanidentifier,keyword,punctuation,literal,oroperator.

Inmostcases,tokensaregeneratedfromthecharactersofaSwiftsourcefilebyconsideringthelongestpossiblesubstringfromtheinputtext,withintheconstraintsofthegrammarthatarespecifiedbelow.Thisbehaviorisreferredtoaslongestmatchormaximalmunch.

WhitespaceandComments

Whitespacehastwouses:toseparatetokensinthesourcefileandtohelpdeterminewhetheranoperatorisaprefixorpostfix(seeOperators),butisotherwiseignored.Thefollowingcharactersareconsideredwhitespace:space(U+0020),linefeed(U+000A),carriagereturn(U+000D),horizontaltab(U+0009),verticaltab(U+000B),formfeed(U+000C)andnull(U+0000).

Commentsaretreatedaswhitespacebythecompiler.Singlelinecommentsbeginwith//andcontinueuntilalinefeed(U+000A)orcarriagereturn(U+000D).Multilinecommentsbeginwith/*andendwith*/.Nestingmultilinecommentsisallowed,butthecommentmarkersmustbebalanced.

Commentscancontainadditionalformattingandmarkup,asdescribedinMarkupFormattingReference.

GRAMMAR OF WH I TESPACE

whitespace → whitespace-item whitespace optwhitespace-item → line-breakwhitespace-item → commentwhitespace-item → multiline-commentwhitespace-item → U+0000,U+0009,U+000B,U+000C,orU+0020

Page 538: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

line-break → U+000Aline-break → U+000Dline-break → U+000DfollowedbyU+000Acomment → // comment-text line-breakmultiline-comment → /* multiline-comment-text */comment-text → comment-text-item comment-text optcomment-text-item → AnyUnicodescalarvalueexceptU+000AorU+000Dmultiline-comment-text → multiline-comment-text-item multiline-comment-text optmultiline-comment-text-item → multiline-commentmultiline-comment-text-item → comment-text-itemmultiline-comment-text-item → AnyUnicodescalarvalueexcept /* or */

Identifiers

IdentifiersbeginwithanuppercaseorlowercaseletterAthroughZ,anunderscore(_),anoncombiningalphanumericUnicodecharacterintheBasicMultilingualPlane,oracharacteroutsidetheBasicMultilingualPlanethatisn’tinaPrivateUseArea.Afterthefirstcharacter,digitsandcombiningUnicodecharactersarealsoallowed.

Touseareservedwordasanidentifier,putabacktick(`)beforeandafterit.Forexample,classisnotavalididentifier,but`class`isvalid.Thebackticksaren’tconsideredpartoftheidentifier;`x`andxhavethesamemeaning.

Insideaclosurewithnoexplicitparameternames,theparametersareimplicitlynamed$0,$1,$2,andsoon.Thesenamesarevalididentifierswithinthescopeoftheclosure.

Thecompilersynthesizesidentifiersthatbeginwithadollarsign($)forpropertiesthathaveapropertywrapperprojection.Yourcodecaninteractwiththeseidentifiers,butyoucan’tdeclareidentifierswiththatprefix.Formoreinformation,seethepropertyWrappersectionoftheAttributeschapter.

GRAMMAR OF AN I DENT I F I ER

identifier → identifier-head identifier-characters optidentifier → ` identifier-head identifier-characters opt `identifier → implicit-parameter-nameidentifier → property-wrapper-projection

Page 539: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

identifier-list → identifier | identifier , identifier-listidentifier-head → Upper-orlowercaseletterAthroughZidentifier-head → _identifier-head → U+00A8,U+00AA,U+00AD,U+00AF,U+00B2–U+00B5,orU+00B7–

U+00BAidentifier-head → U+00BC–U+00BE,U+00C0–U+00D6,U+00D8–U+00F6,orU+00F8–

U+00FFidentifier-head → U+0100–U+02FF,U+0370–U+167F,U+1681–U+180D,orU+180F–

U+1DBFidentifier-head → U+1E00–U+1FFFidentifier-head → U+200B–U+200D,U+202A–U+202E,U+203F–U+2040,U+2054,or

U+2060–U+206Fidentifier-head → U+2070–U+20CF,U+2100–U+218F,U+2460–U+24FF,orU+2776–

U+2793identifier-head → U+2C00–U+2DFForU+2E80–U+2FFFidentifier-head → U+3004–U+3007,U+3021–U+302F,U+3031–U+303F,orU+3040–

U+D7FFidentifier-head → U+F900–U+FD3D,U+FD40–U+FDCF,U+FDF0–U+FE1F,orU+FE30–

U+FE44identifier-head → U+FE47–U+FFFDidentifier-head → U+10000–U+1FFFD,U+20000–U+2FFFD,U+30000–U+3FFFD,or

U+40000–U+4FFFDidentifier-head → U+50000–U+5FFFD,U+60000–U+6FFFD,U+70000–U+7FFFD,or

U+80000–U+8FFFDidentifier-head → U+90000–U+9FFFD,U+A0000–U+AFFFD,U+B0000–U+BFFFD,or

U+C0000–U+CFFFDidentifier-head → U+D0000–U+DFFFDorU+E0000–U+EFFFDidentifier-character → Digit0through9identifier-character → U+0300–U+036F,U+1DC0–U+1DFF,U+20D0–U+20FF,or

U+FE20–U+FE2Fidentifier-character → identifier-headidentifier-characters → identifier-character identifier-characters optimplicit-parameter-name → $ decimal-digitsproperty-wrapper-projection → $ identifier-characters

KeywordsandPunctuation

Thefollowingkeywordsarereservedandcan’tbeusedasidentifiers,unlessthey’reescapedwithbackticks,asdescribedaboveinIdentifiers.Keywordsotherthaninout,var,andletcanbeusedasparameternamesinafunctiondeclarationorfunctioncallwithoutbeingescapedwithbackticks.Whenamemberhasthesamenameasakeyword,referencestothatmemberdon’tneedtobeescapedwithbackticks,exceptwhenthere’sambiguitybetweenreferring

Page 540: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

tothememberandusingthekeyword—forexample,self,Type,andProtocolhavespecialmeaninginanexplicitmemberexpression,sotheymustbeescapedwithbackticksinthatcontext.

Keywordsusedindeclarations:associatedtype,class,deinit,enum,extension,fileprivate,func,import,init,inout,internal,let,open,operator,private,protocol,public,rethrows,static,struct,subscript,typealias,andvar.

Keywordsusedinstatements:break,case,continue,default,defer,do,else,fallthrough,for,guard,if,in,repeat,return,switch,where,andwhile.

Keywordsusedinexpressionsandtypes:as,Any,catch,false,is,nil,super,self,Self,throw,throws,true,andtry.

Keywordsusedinpatterns:_.

Keywordsthatbeginwithanumbersign(#):#available,#colorLiteral,#column,#else,#elseif,#endif,#error,#file,#fileLiteral,#function,#if,#imageLiteral,#line,#selector,#sourceLocation,and#warning.

Keywordsreservedinparticularcontexts:associativity,convenience,dynamic,didSet,final,get,infix,indirect,lazy,left,mutating,none,nonmutating,optional,override,postfix,precedence,prefix,Protocol,required,right,set,Type,unowned,weak,andwillSet.Outsidethecontextinwhichtheyappearinthegrammar,theycanbeusedasidentifiers.

Thefollowingtokensarereservedaspunctuationandcan’tbeusedascustomoperators:(,),{,},[,],.,,,:,;,=,@,#,&(asaprefixoperator),->,`,?,and!(asapostfixoperator).

Literals

Aliteralisthesourcecoderepresentationofavalueofatype,suchasanumberorstring.

Page 541: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thefollowingareexamplesofliterals:

1 42//Integerliteral

2 3.14159//Floating-pointliteral

3 "Hello,world!"//Stringliteral

4 true//Booleanliteral

Aliteraldoesn’thaveatypeonitsown.Instead,aliteralisparsedashavinginfiniteprecisionandSwift’stypeinferenceattemptstoinferatypefortheliteral.Forexample,inthedeclarationletx:Int8=42,Swiftusestheexplicittypeannotation(:Int8)toinferthatthetypeoftheintegerliteral42isInt8.Ifthereisn’tsuitabletypeinformationavailable,Swiftinfersthattheliteral’stypeisoneofthedefaultliteraltypesdefinedintheSwiftstandardlibrary.ThedefaulttypesareIntforintegerliterals,Doubleforfloating-pointliterals,Stringforstringliterals,andBoolforBooleanliterals.Forexample,inthedeclarationletstr="Hello,world",thedefaultinferredtypeofthestringliteral"Hello,world"isString.

Whenspecifyingthetypeannotationforaliteralvalue,theannotation’stypemustbeatypethatcanbeinstantiatedfromthatliteralvalue.Thatis,thetypemustconformtooneofthefollowingSwiftstandardlibraryprotocols:ExpressibleByIntegerLiteralforintegerliterals,ExpressibleByFloatLiteralforfloating-pointliterals,ExpressibleByStringLiteralforstringliterals,ExpressibleByBooleanLiteralforBooleanliterals,ExpressibleByUnicodeScalarLiteralforstringliteralsthatcontainonlyasingleUnicodescalar,andExpressibleByExtendedGraphemeClusterLiteralforstringliteralsthatcontainonlyasingleextendedgraphemecluster.Forexample,Int8conformstotheExpressibleByIntegerLiteralprotocol,andthereforeitcanbeusedinthetypeannotationfortheintegerliteral42inthedeclarationletx:Int8=42.

GRAMMAR OF A L I TERAL

literal → numeric-literal | string-literal | boolean-literal | nil-literalnumeric-literal → -opt integer-literal | -opt floating-point-literalboolean-literal → true | falsenil-literal → nil

Page 542: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

IntegerLiteralsIntegerliteralsrepresentintegervaluesofunspecifiedprecision.Bydefault,integerliteralsareexpressedindecimal;youcanspecifyanalternatebaseusingaprefix.Binaryliteralsbeginwith0b,octalliteralsbeginwith0o,andhexadecimalliteralsbeginwith0x.

Decimalliteralscontainthedigits0through9.Binaryliteralscontain0and1,octalliteralscontain0through7,andhexadecimalliteralscontain0through9aswellasAthroughFinupper-orlowercase.

Negativeintegersliteralsareexpressedbyprependingaminussign(-)toanintegerliteral,asin-42.

Underscores(_)areallowedbetweendigitsforreadability,butthey’reignoredandthereforedon’taffectthevalueoftheliteral.Integerliteralscanbeginwithleadingzeros(0),butthey’relikewiseignoredanddon’taffectthebaseorvalueoftheliteral.

Unlessotherwisespecified,thedefaultinferredtypeofanintegerliteralistheSwiftstandardlibrarytypeInt.TheSwiftstandardlibraryalsodefinestypesforvarioussizesofsignedandunsignedintegers,asdescribedinIntegers.

GRAMMAR OF AN I NTEGER L I TERAL

integer-literal → binary-literalinteger-literal → octal-literalinteger-literal → decimal-literalinteger-literal → hexadecimal-literalbinary-literal → 0b binary-digit binary-literal-characters optbinary-digit → Digit0or1binary-literal-character → binary-digit | _binary-literal-characters → binary-literal-character binary-literal-characters optoctal-literal → 0o octal-digit octal-literal-characters optoctal-digit → Digit0through7octal-literal-character → octal-digit | _octal-literal-characters → octal-literal-character octal-literal-characters optdecimal-literal → decimal-digit decimal-literal-characters optdecimal-digit → Digit0through9decimal-digits → decimal-digit decimal-digits optdecimal-literal-character → decimal-digit | _decimal-literal-characters → decimal-literal-character decimal-literal-characters opthexadecimal-literal → 0x hexadecimal-digit hexadecimal-literal-characters opt

Page 543: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

hexadecimal-digit → Digit0through9,athroughf,orAthroughFhexadecimal-literal-character → hexadecimal-digit | _hexadecimal-literal-characters → hexadecimal-literal-character hexadecimal-literal-

characters opt

Floating-PointLiteralsFloating-pointliteralsrepresentfloating-pointvaluesofunspecifiedprecision.

Bydefault,floating-pointliteralsareexpressedindecimal(withnoprefix),buttheycanalsobeexpressedinhexadecimal(witha0xprefix).

Decimalfloating-pointliteralsconsistofasequenceofdecimaldigitsfollowedbyeitheradecimalfraction,adecimalexponent,orboth.Thedecimalfractionconsistsofadecimalpoint(.)followedbyasequenceofdecimaldigits.Theexponentconsistsofanupper-orlowercaseeprefixfollowedbyasequenceofdecimaldigitsthatindicateswhatpowerof10thevalueprecedingtheeismultipliedby.Forexample,1.25e2represents1.25x102,whichevaluatesto125.0.Similarly,1.25e-2represents1.25x10-2,whichevaluatesto0.0125.

Hexadecimalfloating-pointliteralsconsistofa0xprefix,followedbyanoptionalhexadecimalfraction,followedbyahexadecimalexponent.Thehexadecimalfractionconsistsofadecimalpointfollowedbyasequenceofhexadecimaldigits.Theexponentconsistsofanupper-orlowercasepprefixfollowedbyasequenceofdecimaldigitsthatindicateswhatpowerof2thevalueprecedingthepismultipliedby.Forexample,0xFp2represents15x22,whichevaluatesto60.Similarly,0xFp-2represents15x2-2,whichevaluatesto3.75.

Negativefloating-pointliteralsareexpressedbyprependingaminussign(-)toafloating-pointliteral,asin-42.5.

Underscores(_)areallowedbetweendigitsforreadability,butthey’reignoredandthereforedon’taffectthevalueoftheliteral.Floating-pointliteralscanbeginwithleadingzeros(0),butthey’relikewiseignoredanddon’taffectthebaseorvalueoftheliteral.

Page 544: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Unlessotherwisespecified,thedefaultinferredtypeofafloating-pointliteralistheSwiftstandardlibrarytypeDouble,whichrepresentsa64-bitfloating-pointnumber.TheSwiftstandardlibraryalsodefinesaFloattype,whichrepresentsa32-bitfloating-pointnumber.

GRAMMAR OF A F LOAT ING -PO INT L I TERAL

floating-point-literal → decimal-literal decimal-fraction opt decimal-exponent optfloating-point-literal → hexadecimal-literal hexadecimal-fraction opt hexadecimal-

exponentdecimal-fraction → . decimal-literaldecimal-exponent → floating-point-e sign opt decimal-literalhexadecimal-fraction → . hexadecimal-digit hexadecimal-literal-characters opthexadecimal-exponent → floating-point-p sign opt decimal-literalfloating-point-e → e | Efloating-point-p → p | Psign → + | -

StringLiteralsAstringliteralisasequenceofcharacterssurroundedbyquotationmarks.Asingle-linestringliteralissurroundedbydoublequotationmarksandhasthefollowingform:

" characters "

Stringliteralscan’tcontainanunescapeddoublequotationmark("),anunescapedbackslash(\),acarriagereturn,oralinefeed.

Amultilinestringliteralissurroundedbythreedoublequotationmarksandhasthefollowingform:

"""

characters

"""

Unlikeasingle-linestringliteral,amultilinestringliteralcancontainunescapeddoublequotationmarks("),carriagereturns,andlinefeeds.Itcan’tcontainthree

Page 545: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

unescapeddoublequotationmarksnexttoeachother.

Thelinebreakafterthe"""thatbeginsthemultilinestringliteralisnotpartofthestring.Thelinebreakbeforethe"""thatendstheliteralisalsonotpartofthestring.Tomakeamultilinestringliteralthatbeginsorendswithalinefeed,writeablanklineasitsfirstorlastline.

Amultilinestringliteralcanbeindentedusinganycombinationofspacesandtabs;thisindentationisnotincludedinthestring.The"""thatendstheliteraldeterminestheindentation:Everynonblanklineintheliteralmustbeginwithexactlythesameindentationthatappearsbeforetheclosing""";there’snoconversionbetweentabsandspaces.Youcanincludeadditionalspacesandtabsafterthatindentation;thosespacesandtabsappearinthestring.

Linebreaksinamultilinestringliteralarenormalizedtousethelinefeedcharacter.Evenifyoursourcefilehasamixofcarriagereturnsandlinefeeds,allofthelinebreaksinthestringwillbethesame.

Inamultilinestringliteral,writingabackslash(\)attheendofalineomitsthatlinebreakfromthestring.Anywhitespacebetweenthebackslashandthelinebreakisalsoomitted.Youcanusethissyntaxtohardwrapamultilinestringliteralinyoursourcecode,withoutchangingthevalueoftheresultingstring.

Specialcharacterscanbeincludedinstringliteralsofboththesingle-lineandmultilineformsusingthefollowingescapesequences:

Nullcharacter(\0)

Backslash(\\)

Horizontaltab(\t)

Linefeed(\n)

Carriagereturn(\r)

Doublequotationmark(\")

Singlequotationmark(\')

Page 546: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Unicodescalar(\u{n}),wherenisahexadecimalnumberthathasonetoeightdigits

Thevalueofanexpressioncanbeinsertedintoastringliteralbyplacingtheexpressioninparenthesesafterabackslash(\).Theinterpolatedexpressioncancontainastringliteral,butcan’tcontainanunescapedbackslash,acarriagereturn,oralinefeed.

Forexample,allofthefollowingstringliteralshavethesamevalue:

1 "123"

2 "12\("3")"

3 "12\(3)"

4 "12\(1+2)"

5 letx=3;"12\(x)"

Astringdelimitedbyextendeddelimitersisasequenceofcharacterssurroundedbyquotationmarksandabalancedsetofoneormorenumbersigns(#).Astringdelimitedbyextendeddelimitershasthefollowingforms:

#" characters "#

#"""

characters

"""#

Specialcharactersinastringdelimitedbyextendeddelimitersappearintheresultingstringasnormalcharactersratherthanasspecialcharacters.Youcanuseextendeddelimiterstocreatestringswithcharactersthatwouldordinarilyhaveaspecialeffectsuchasgeneratingastringinterpolation,startinganescapesequence,orterminatingthestring.

Thefollowingexampleshowsastringliteralandastringdelimitedbyextendeddelimitersthatcreateequivalentstringvalues:

Page 547: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letstring=#"\(x)\"\u{2603}"#

2 letescaped="\\(x)\\\"\\u{2603}"

3 print(string)

4 //Prints"\(x)\"\u{2603}"

5 print(string==escaped)

6 //Prints"true"

Ifyouusemorethanonenumbersigntoformastringdelimitedbyextendeddelimiters,don’tplacewhitespaceinbetweenthenumbersigns:

1 print(###"Line1\###nLine2"###)//OK

2 print(###"Line1\###nLine2"###)//Error

Multilinestringliteralsthatyoucreateusingextendeddelimitershavethesameindentationrequirementsasregularmultilinestringliterals.

ThedefaultinferredtypeofastringliteralisString.FormoreinformationabouttheStringtype,seeStringsandCharactersandString.

Stringliteralsthatareconcatenatedbythe+operatorareconcatenatedatcompiletime.Forexample,thevaluesoftextAandtextBintheexamplebelowareidentical—noruntimeconcatenationisperformed.

1 lettextA="Hello"+"world"

2 lettextB="Helloworld"

GRAMMAR OF A STR ING L I TERAL

string-literal → static-string-literal | interpolated-string-literalstring-literal-opening-delimiter → extended-string-literal-delimiter opt "string-literal-closing-delimiter → " extended-string-literal-delimiter optstatic-string-literal → string-literal-opening-delimiter quoted-text opt string-literal-closing-

delimiterstatic-string-literal → multiline-string-literal-opening-delimiter multiline-quoted-text opt

multiline-string-literal-closing-delimitermultiline-string-literal-opening-delimiter → extended-string-literal-delimiter """multiline-string-literal-closing-delimiter → """ extended-string-literal-delimiter

Page 548: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

extended-string-literal-delimiter → # extended-string-literal-delimiter optquoted-text → quoted-text-item quoted-text optquoted-text-item → escaped-characterquoted-text-item → AnyUnicodescalarvalueexcept " , \ ,U+000A,orU+000Dmultiline-quoted-text → multiline-quoted-text-item multiline-quoted-text optmultiline-quoted-text-item → escaped-charactermultiline-quoted-text-item → AnyUnicodescalarvalueexcept \multiline-quoted-text-item → escaped-newlineinterpolated-string-literal → string-literal-opening-delimiter interpolated-text opt string-

literal-closing-delimiterinterpolated-string-literal → multiline-string-literal-opening-delimiter interpolated-text opt

multiline-string-literal-closing-delimiterinterpolated-text → interpolated-text-item interpolated-text optinterpolated-text-item → \( expression ) | quoted-text-itemmultiline-interpolated-text → multiline-interpolated-text-item multiline-interpolated-text optmultiline-interpolated-text-item → \( expression ) |multiline-quoted-text-itemescape-sequence → \ extended-string-literal-delimiterescaped-character → escape-sequence 0 | escape-sequence \ | escape-sequence t |

escape-sequence n | escape-sequence r | escape-sequence " | escape-sequence'

escaped-character → escape-sequence u { unicode-scalar-digits }unicode-scalar-digits → Betweenoneandeighthexadecimaldigitsescaped-newline → escape-sequence whitespace opt line-break

Operators

TheSwiftstandardlibrarydefinesanumberofoperatorsforyouruse,manyofwhicharediscussedinBasicOperatorsandAdvancedOperators.Thepresentsectiondescribeswhichcharacterscanbeusedtodefinecustomoperators.

CustomoperatorscanbeginwithoneoftheASCIIcharacters/,=,-,+,!,*,%,<,>,&,|,^,?,or~,oroneoftheUnicodecharactersdefinedinthegrammarbelow(whichincludecharactersfromtheMathematicalOperators,MiscellaneousSymbols,andDingbatsUnicodeblocks,amongothers).Afterthefirstcharacter,combiningUnicodecharactersarealsoallowed.

Youcanalsodefinecustomoperatorsthatbeginwithadot(.).Theseoperatorscancontainadditionaldots.Forexample,.+.istreatedasasingleoperator.Ifanoperatordoesn’tbeginwithadot,itcan’tcontainadotelsewhere.Forexample,

Page 549: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

+.+istreatedasthe+operatorfollowedbythe.+operator.

Althoughyoucandefinecustomoperatorsthatcontainaquestionmark(?),theycan’tconsistofasinglequestionmarkcharacteronly.Additionally,althoughoperatorscancontainanexclamationmark(!),postfixoperatorscan’tbeginwitheitheraquestionmarkoranexclamationmark.

NOTE

Thetokens=,->,//,/*,*/,.,theprefixoperators<,&,and?,theinfixoperator?,andthepostfixoperators>,!,and?arereserved.Thesetokenscan’tbeoverloaded,norcantheybeusedascustomoperators.

Thewhitespacearoundanoperatorisusedtodeterminewhetheranoperatorisusedasaprefixoperator,apostfixoperator,orabinaryoperator.Thisbehaviorissummarizedinthefollowingrules:

Ifanoperatorhaswhitespacearoundbothsidesoraroundneitherside,it’streatedasabinaryoperator.Asanexample,the+++operatorina+++banda+++bistreatedasabinaryoperator.

Ifanoperatorhaswhitespaceontheleftsideonly,it’streatedasaprefixunaryoperator.Asanexample,the+++operatorina+++bistreatedasaprefixunaryoperator.

Ifanoperatorhaswhitespaceontherightsideonly,it’streatedasapostfixunaryoperator.Asanexample,the+++operatorina+++bistreatedasapostfixunaryoperator.

Ifanoperatorhasnowhitespaceontheleftbutisfollowedimmediatelybyadot(.),it’streatedasapostfixunaryoperator.Asanexample,the+++operatorina+++.bistreatedasapostfixunaryoperator(a+++.bratherthana+++.b).

Forthepurposesoftheserules,thecharacters(,[,and{beforeanoperator,thecharacters),],and}afteranoperator,andthecharacters,,;,and:arealsoconsideredwhitespace.

There’sonecaveattotherulesabove.Ifthe!or?predefinedoperatorhasno

Page 550: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

whitespaceontheleft,it’streatedasapostfixoperator,regardlessofwhetherithaswhitespaceontheright.Tousethe?astheoptional-chainingoperator,itmustnothavewhitespaceontheleft.Touseitintheternaryconditional(?:)operator,itmusthavewhitespacearoundbothsides.

Incertainconstructs,operatorswithaleading<or>maybesplitintotwoormoretokens.Theremainderistreatedthesamewayandmaybesplitagain.Asaresult,there’snoneedtousewhitespacetodisambiguatebetweentheclosing>charactersinconstructslikeDictionary<String,Array<Int>>.Inthisexample,theclosing>charactersarenottreatedasasingletokenthatmaythenbemisinterpretedasabitshift>>operator.

Tolearnhowtodefinenew,customoperators,seeCustomOperatorsandOperatorDeclaration.Tolearnhowtooverloadexistingoperators,seeOperatorMethods.

GRAMMAR OF OPERATORS

operator → operator-head operator-characters optoperator → dot-operator-head dot-operator-charactersoperator-head → / | = | - | + | ! | * | % | < | > | & | | | ^ | ~ | ?operator-head → U+00A1–U+00A7operator-head → U+00A9orU+00ABoperator-head → U+00ACorU+00AEoperator-head → U+00B0–U+00B1operator-head → U+00B6,U+00BB,U+00BF,U+00D7,orU+00F7operator-head → U+2016–U+2017operator-head → U+2020–U+2027operator-head → U+2030–U+203Eoperator-head → U+2041–U+2053operator-head → U+2055–U+205Eoperator-head → U+2190–U+23FFoperator-head → U+2500–U+2775operator-head → U+2794–U+2BFFoperator-head → U+2E00–U+2E7Foperator-head → U+3001–U+3003operator-head → U+3008–U+3020operator-head → U+3030operator-character → operator-headoperator-character → U+0300–U+036Foperator-character → U+1DC0–U+1DFFoperator-character → U+20D0–U+20FFoperator-character → U+FE00–U+FE0Foperator-character → U+FE20–U+FE2Foperator-character → U+E0100–U+E01EF

Page 551: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

operator-characters → operator-character operator-characters optdot-operator-head → .dot-operator-character → . | operator-characterdot-operator-characters → dot-operator-character dot-operator-characters optbinary-operator → operatorprefix-operator → operatorpostfix-operator → operator

Page 552: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Types

InSwift,therearetwokindsoftypes:namedtypesandcompoundtypes.Anamedtypeisatypethatcanbegivenaparticularnamewhenit’sdefined.Namedtypesincludeclasses,structures,enumerations,andprotocols.Forexample,instancesofauser-definedclassnamedMyClasshavethetypeMyClass.Inadditiontouser-definednamedtypes,theSwiftstandardlibrarydefinesmanycommonlyusednamedtypes,includingthosethatrepresentarrays,dictionaries,andoptionalvalues.

Datatypesthatarenormallyconsideredbasicorprimitiveinotherlanguages—suchastypesthatrepresentnumbers,characters,andstrings—areactuallynamedtypes,definedandimplementedintheSwiftstandardlibraryusingstructures.Becausethey’renamedtypes,youcanextendtheirbehaviortosuittheneedsofyourprogram,usinganextensiondeclaration,discussedinExtensionsandExtensionDeclaration.

Acompoundtypeisatypewithoutaname,definedintheSwiftlanguageitself.Therearetwocompoundtypes:functiontypesandtupletypes.Acompoundtypemaycontainnamedtypesandothercompoundtypes.Forexample,thetupletype(Int,(Int,Int))containstwoelements:ThefirstisthenamedtypeInt,andthesecondisanothercompoundtype(Int,Int).

Youcanputparenthesesaroundanamedtypeoracompoundtype.However,addingparenthesesaroundatypedoesn’thaveanyeffect.Forexample,(Int)isequivalenttoInt.

ThischapterdiscussesthetypesdefinedintheSwiftlanguageitselfanddescribesthetypeinferencebehaviorofSwift.

GRAMMAR OF ATYPE

type → function-typetype → array-typetype → dictionary-typetype → type-identifiertype → tuple-typetype → optional-typetype → implicitly-unwrapped-optional-type

Page 553: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

type → protocol-composition-typetype → opaque-typetype → metatype-typetype → self-typetype → Anytype → ( type )

TypeAnnotation

Atypeannotationexplicitlyspecifiesthetypeofavariableorexpression.Typeannotationsbeginwithacolon(:)andendwithatype,asthefollowingexamplesshow:

1 letsomeTuple:(Double,Double)=(3.14159,2.71828)

2 funcsomeFunction(a:Int){/*...*/}

Inthefirstexample,theexpressionsomeTupleisspecifiedtohavethetupletype(Double,Double).Inthesecondexample,theparameteratothefunctionsomeFunctionisspecifiedtohavethetypeInt.

Typeannotationscancontainanoptionallistoftypeattributesbeforethetype.

GRAMMAR OF ATYPE ANNOTAT ION

type-annotation → : attributes opt inoutopt type

TypeIdentifier

Atypeidentifierreferstoeitheranamedtypeoratypealiasofanamedorcompoundtype.

Mostofthetime,atypeidentifierdirectlyreferstoanamedtypewiththesamenameastheidentifier.Forexample,IntisatypeidentifierthatdirectlyreferstothenamedtypeInt,andthetypeidentifierDictionary<String,Int>directly

Page 554: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

referstothenamedtypeDictionary<String,Int>.

Therearetwocasesinwhichatypeidentifierdoesn’trefertoatypewiththesamename.Inthefirstcase,atypeidentifierreferstoatypealiasofanamedorcompoundtype.Forinstance,intheexamplebelow,theuseofPointinthetypeannotationreferstothetupletype(Int,Int).

1 typealiasPoint=(Int,Int)

2 letorigin:Point=(0,0)

Inthesecondcase,atypeidentifierusesdot(.)syntaxtorefertonamedtypesdeclaredinothermodulesornestedwithinothertypes.Forexample,thetypeidentifierinthefollowingcodereferencesthenamedtypeMyTypethatisdeclaredintheExampleModulemodule.

varsomeValue:ExampleModule.MyType

GRAMMAR OF ATYPE I DENT I F I ER

type-identifier → type-name generic-argument-clause opt | type-name generic-argument-clause opt . type-identifier

type-name → identifier

TupleType

Atupletypeisacomma-separatedlistoftypes,enclosedinparentheses.

Youcanuseatupletypeasthereturntypeofafunctiontoenablethefunctiontoreturnasingletuplecontainingmultiplevalues.Youcanalsonametheelementsofatupletypeandusethosenamestorefertothevaluesoftheindividualelements.Anelementnameconsistsofanidentifierfollowedimmediatelybyacolon(:).Foranexamplethatdemonstratesbothofthesefeatures,seeFunctionswithMultipleReturnValues.

Whenanelementofatupletypehasaname,thatnameispartofthetype.

Page 555: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 varsomeTuple=(top:10,bottom:12)//someTupleisoftype

(top:Int,bottom:Int)

2 someTuple=(top:4,bottom:42)//OK:namesmatch

3 someTuple=(9,99)//OK:namesareinferred

4 someTuple=(left:5,right:5)//Error:namesdon'tmatch

Alltupletypescontaintwoormoretypes,exceptforVoidwhichisatypealiasfortheemptytupletype,().

GRAMMAR OF ATUPLE TYPE

tuple-type → ( ) | ( tuple-type-element , tuple-type-element-list )tuple-type-element-list → tuple-type-element | tuple-type-element , tuple-type-element-

listtuple-type-element → element-name type-annotation | typeelement-name → identifier

FunctionType

Afunctiontyperepresentsthetypeofafunction,method,orclosureandconsistsofaparameterandreturntypeseparatedbyanarrow(->):

( parametertype )-> returntype

Theparametertypeiscomma-separatedlistoftypes.Becausethereturntypecanbeatupletype,functiontypessupportfunctionsandmethodsthatreturnmultiplevalues.

Aparameterofthefunctiontype()->T(whereTisanytype)canapplytheautoclosureattributetoimplicitlycreateaclosureatitscallsites.Thisprovidesasyntacticallyconvenientwaytodefertheevaluationofanexpressionwithoutneedingtowriteanexplicitclosurewhenyoucallthefunction.Foranexampleofanautoclosurefunctiontypeparameter,seeAutoclosures.

Afunctiontypecanhaveavariadicparameterinitsparametertype.Syntactically,avariadicparameterconsistsofabasetypenamefollowed

Page 556: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

immediatelybythreedots(...),asinInt....Avariadicparameteristreatedasanarraythatcontainselementsofthebasetypename.Forinstance,thevariadicparameterInt...istreatedas[Int].Foranexamplethatusesavariadicparameter,seeVariadicParameters.

Tospecifyanin-outparameter,prefixtheparametertypewiththeinoutkeyword.Youcan’tmarkavariadicparameterorareturntypewiththeinoutkeyword.In-outparametersarediscussedinIn-OutParameters.

Ifafunctiontypehasonlyoneparameterandthatparameter’stypeisatupletype,thenthetupletypemustbeparenthesizedwhenwritingthefunction’stype.Forexample,((Int,Int))->Voidisthetypeofafunctionthattakesasingleparameterofthetupletype(Int,Int)anddoesn’treturnanyvalue.Incontrast,withoutparentheses,(Int,Int)->VoidisthetypeofafunctionthattakestwoIntparametersanddoesn’treturnanyvalue.Likewise,becauseVoidisatypealiasfor(),thefunctiontype(Void)->Voidisthesameas(())->()—afunctionthattakesasingleargumentthatisanemptytuple.Thesetypesarenotthesameas()->()—afunctionthattakesnoarguments.

Argumentnamesinfunctionsandmethodsarenotpartofthecorrespondingfunctiontype.Forexample:

1 funcsomeFunction(left:Int,right:Int){}

2 funcanotherFunction(left:Int,right:Int){}

3 funcfunctionWithDifferentLabels(top:Int,bottom:Int){}

4

5 varf=someFunction//Thetypeoffis(Int,Int)->Void,

not(left:Int,right:Int)->Void.

6 f=anotherFunction//OK

7 f=functionWithDifferentLabels//OK

8

9 funcfunctionWithDifferentArgumentTypes(left:Int,right:

String){}

10 f=functionWithDifferentArgumentTypes//Error

Page 557: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

11

12 funcfunctionWithDifferentNumberOfArguments(left:Int,right:

Int,top:Int){}

13 f=functionWithDifferentNumberOfArguments//Error

Becauseargumentlabelsarenotpartofafunction’stype,youomitthemwhenwritingafunctiontype.

1 varoperation:(lhs:Int,rhs:Int)->Int//Error

2 varoperation:(_lhs:Int,_rhs:Int)->Int//OK

3 varoperation:(Int,Int)->Int//OK

Ifafunctiontypeincludesmorethanasinglearrow(->),thefunctiontypesaregroupedfromrighttoleft.Forexample,thefunctiontype(Int)->(Int)->Intisunderstoodas(Int)->((Int)->Int)—thatis,afunctionthattakesanIntandreturnsanotherfunctionthattakesandreturnsanInt.

Functiontypesthatcanthroworrethrowanerrormustbemarkedwiththethrowskeyword.Thethrowskeywordispartofafunction’stype,andnonthrowingfunctionsaresubtypesofthrowingfunctions.Asaresult,youcanuseanonthrowingfunctioninthesameplacesasathrowingone.ThrowingandrethrowingfunctionsaredescribedinThrowingFunctionsandMethodsandRethrowingFunctionsandMethods.

RestrictionsforNonescapingClosuresAparameterthat’sanonescapingfunctioncan’tbestoredinaproperty,variable,orconstantoftypeAny,becausethatmightallowthevaluetoescape.

Aparameterthat’sanonescapingfunctioncan’tbepassedasanargumenttoanothernonescapingfunctionparameter.ThisrestrictionhelpsSwiftperformmoreofitschecksforconflictingaccesstomemoryatcompiletimeinsteadofatruntime.Forexample:

Page 558: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 letexternal:(()->Void)->Void={_in()}

2 functakesTwoFunctions(first:(()->Void)->Void,second:(()

->Void)->Void){

3 first{first{}}//Error

4 second{second{}}//Error

5

6 first{second{}}//Error

7 second{first{}}//Error

8

9 first{external{}}//OK

10 external{first{}}//OK

11 }

Inthecodeabove,bothoftheparameterstotakesTwoFunctions(first:second:)arefunctions.Neitherparameterismarked@escaping,sothey’rebothnonescapingasaresult.

Thefourfunctioncallsmarked“Error”intheexampleabovecausecompilererrors.Becausethefirstandsecondparametersarenonescapingfunctions,theycan’tbepassedasargumentstoanothernonescapingfunctionparameter.Incontrast,thetwofunctioncallsmarked“OK”don’tcauseacompilererror.Thesefunctioncallsdon’tviolatetherestrictionbecauseexternalisn’toneoftheparametersoftakesTwoFunctions(first:second:).

Ifyouneedtoavoidthisrestriction,markoneoftheparametersasescaping,ortemporarilyconvertoneofthenonescapingfunctionparameterstoanescapingfunctionbyusingthewithoutActuallyEscaping(_:do:)function.Forinformationaboutavoidingconflictingaccesstomemory,seeMemorySafety.

GRAMMAR OF A FUNCT ION TYPE

function-type → attributes opt function-type-argument-clause throwsopt -> typefunction-type-argument-clause → ( )function-type-argument-clause → ( function-type-argument-list ...opt )function-type-argument-list → function-type-argument | function-type-argument ,

function-type-argument-list

Page 559: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

function-type-argument → attributes opt inoutopt type | argument-label type-annotation

argument-label → identifier

ArrayType

TheSwiftlanguageprovidesthefollowingsyntacticsugarfortheSwiftstandardlibraryArray<Element>type:

[ type ]

Inotherwords,thefollowingtwodeclarationsareequivalent:

1 letsomeArray:Array<String>=["Alex","Brian","Dave"]

2 letsomeArray:[String]=["Alex","Brian","Dave"]

Inbothcases,theconstantsomeArrayisdeclaredasanarrayofstrings.Theelementsofanarraycanbeaccessedthroughsubscriptingbyspecifyingavalidindexvalueinsquarebrackets:someArray[0]referstotheelementatindex0,"Alex".

Youcancreatemultidimensionalarraysbynestingpairsofsquarebrackets,wherethenameofthebasetypeoftheelementsiscontainedintheinnermostpairofsquarebrackets.Forexample,youcancreateathree-dimensionalarrayofintegersusingthreesetsofsquarebrackets:

vararray3D:[[[Int]]]=[[[1,2],[3,4]],[[5,6],[7,8]]]

Whenaccessingtheelementsinamultidimensionalarray,theleft-mostsubscriptindexreferstotheelementatthatindexintheoutermostarray.Thenextsubscriptindextotherightreferstotheelementatthatindexinthearraythat’snestedonelevelin.Andsoon.Thismeansthatintheexampleabove,array3D[0]refersto[[1,2],[3,4]],array3D[0][1]refersto[3,4],andarray3D[0][1][1]referstothevalue4.

Page 560: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ForadetaileddiscussionoftheSwiftstandardlibraryArraytype,seeArrays.

GRAMMAR OF AN ARRAY TYPE

array-type → [ type ]

DictionaryType

TheSwiftlanguageprovidesthefollowingsyntacticsugarfortheSwiftstandardlibraryDictionary<Key,Value>type:

[ keytype : valuetype ]

Inotherwords,thefollowingtwodeclarationsareequivalent:

1 letsomeDictionary:[String:Int]=["Alex":31,"Paul":39]

2 letsomeDictionary:Dictionary<String,Int>=["Alex":31,

"Paul":39]

Inbothcases,theconstantsomeDictionaryisdeclaredasadictionarywithstringsaskeysandintegersasvalues.

Thevaluesofadictionarycanbeaccessedthroughsubscriptingbyspecifyingthecorrespondingkeyinsquarebrackets:someDictionary["Alex"]referstothevalueassociatedwiththekey"Alex".Thesubscriptreturnsanoptionalvalueofthedictionary’svaluetype.Ifthespecifiedkeyisn’tcontainedinthedictionary,thesubscriptreturnsnil.

ThekeytypeofadictionarymustconformtotheSwiftstandardlibraryHashableprotocol.

ForadetaileddiscussionoftheSwiftstandardlibraryDictionarytype,seeDictionaries.

GRAMMAR OF AD ICT IONARY TYPE

Page 561: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

dictionary-type → [ type : type ]

OptionalType

TheSwiftlanguagedefinesthepostfix?assyntacticsugarforthenamedtypeOptional<Wrapped>,whichisdefinedintheSwiftstandardlibrary.Inotherwords,thefollowingtwodeclarationsareequivalent:

1 varoptionalInteger:Int?

2 varoptionalInteger:Optional<Int>

Inbothcases,thevariableoptionalIntegerisdeclaredtohavethetypeofanoptionalinteger.Notethatnowhitespacemayappearbetweenthetypeandthe?.

ThetypeOptional<Wrapped>isanenumerationwithtwocases,noneandsome(Wrapped),whichareusedtorepresentvaluesthatmayormaynotbepresent.Anytypecanbeexplicitlydeclaredtobe(orimplicitlyconvertedto)anoptionaltype.Ifyoudon’tprovideaninitialvaluewhenyoudeclareanoptionalvariableorproperty,itsvalueautomaticallydefaultstonil.

Ifaninstanceofanoptionaltypecontainsavalue,youcanaccessthatvalueusingthepostfixoperator!,asshownbelow:

1 optionalInteger=42

2 optionalInteger!//42

Usingthe!operatortounwrapanoptionalthathasavalueofnilresultsinaruntimeerror.

Youcanalsouseoptionalchainingandoptionalbindingtoconditionallyperformanoperationonanoptionalexpression.Ifthevalueisnil,nooperationisperformedandthereforenoruntimeerrorisproduced.

Formoreinformationandtoseeexamplesthatshowhowtouseoptionaltypes,

Page 562: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

seeOptionals.

GRAMMAR OF AN OPT IONALTYPE

optional-type → type ?

ImplicitlyUnwrappedOptionalType

TheSwiftlanguagedefinesthepostfix!assyntacticsugarforthenamedtypeOptional<Wrapped>,whichisdefinedintheSwiftstandardlibrary,withtheadditionalbehaviorthatit’sautomaticallyunwrappedwhenit’saccessed.Ifyoutrytouseanimplicitlyunwrappedoptionalthathasavalueofnil,you’llgetaruntimeerror.Withtheexceptionoftheimplicitunwrappingbehavior,thefollowingtwodeclarationsareequivalent:

1 varimplicitlyUnwrappedString:String!

2 varexplicitlyUnwrappedString:Optional<String>

Notethatnowhitespacemayappearbetweenthetypeandthe!.

Becauseimplicitunwrappingchangesthemeaningofthedeclarationthatcontainsthattype,optionaltypesthatarenestedinsideatupletypeoragenerictype—suchastheelementtypesofadictionaryorarray—can’tbemarkedasimplicitlyunwrapped.Forexample:

1 lettupleOfImplicitlyUnwrappedElements:(Int!,Int!)//Error

2 letimplicitlyUnwrappedTuple:(Int,Int)!//OK

3

4 letarrayOfImplicitlyUnwrappedElements:[Int!]//Error

5 letimplicitlyUnwrappedArray:[Int]!//OK

BecauseimplicitlyunwrappedoptionalshavethesameOptional<Wrapped>typeasoptionalvalues,youcanuseimplicitlyunwrappedoptionalsinallthesameplacesinyourcodethatyoucanuseoptionals.Forexample,youcanassign

Page 563: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

valuesofimplicitlyunwrappedoptionalstovariables,constants,andpropertiesofoptionals,andviceversa.

Aswithoptionals,ifyoudon’tprovideaninitialvaluewhenyoudeclareanimplicitlyunwrappedoptionalvariableorproperty,itsvalueautomaticallydefaultstonil.

Useoptionalchainingtoconditionallyperformanoperationonanimplicitlyunwrappedoptionalexpression.Ifthevalueisnil,nooperationisperformedandthereforenoruntimeerrorisproduced.

Formoreinformationaboutimplicitlyunwrappedoptionaltypes,seeImplicitlyUnwrappedOptionals.

GRAMMAR OF AN IMPL IC I T LY UNWRAPPED OPT IONALTYPE

implicitly-unwrapped-optional-type → type !

ProtocolCompositionType

Aprotocolcompositiontypedefinesatypethatconformstoeachprotocolinalistofspecifiedprotocols,oratypethatisasubclassofagivenclassandconformstoeachprotocolinalistofspecifiedprotocols.Protocolcompositiontypesmaybeusedonlywhenspecifyingatypeintypeannotations,ingenericparameterclauses,andingenericwhereclauses.

Protocolcompositiontypeshavethefollowingform:

Protocol1 & Protocol2

Aprotocolcompositiontypeallowsyoutospecifyavaluewhosetypeconformstotherequirementsofmultipleprotocolswithoutexplicitlydefininganew,namedprotocolthatinheritsfromeachprotocolyouwantthetypetoconformto.Forexample,youcanusetheprotocolcompositiontypeProtocolA&ProtocolB&ProtocolCinsteadofdeclaringanewprotocolthatinheritsfromProtocolA,ProtocolB,andProtocolC.Likewise,youcanuseSuperClass&ProtocolA

Page 564: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

insteadofdeclaringanewprotocolthatisasubclassofSuperClassandconformstoProtocolA.

Eachiteminaprotocolcompositionlistisoneofthefollowing;thelistcancontainatmostoneclass:

Thenameofaclass

Thenameofaprotocol

Atypealiaswhoseunderlyingtypeisaprotocolcompositiontype,aprotocol,oraclass.

Whenaprotocolcompositiontypecontainstypealiases,it’spossibleforthesameprotocoltoappearmorethanonceinthedefinitions—duplicatesareignored.Forexample,thedefinitionofPQRinthecodebelowisequivalenttoP&Q&R.

1 typealiasPQ=P&Q

2 typealiasPQR=PQ&Q&R

GRAMMAR OF A PROTOCOLCOMPOS I T ION TYPE

protocol-composition-type → type-identifier & protocol-composition-continuationprotocol-composition-continuation → type-identifier | protocol-composition-type

OpaqueType

Anopaquetypedefinesatypethatconformstoaprotocolorprotocolcomposition,withoutspecifyingtheunderlyingconcretetype.

Opaquetypesappearasthereturntypeofafunctionorsubscript,orthetypeofaproperty.Opaquetypescan’tappearaspartofatupletypeoragenerictype,suchastheelementtypeofanarrayorthewrappedtypeofanoptional.

Opaquetypeshavethefollowingform:

Page 565: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

some constraint

Theconstraintisaclasstype,protocoltype,protocolcompositiontype,orAny.Avaluecanbeusedasaninstanceoftheopaquetypeonlyifit’saninstanceofatypethatconformstothelistedprotocolorprotocolcomposition,orinheritsfromthelistedclass.Codethatinteractswithanopaquevaluecanusethevalueonlyinwaysthatarepartoftheinterfacedefinedbytheconstraint.

Protocoldeclarationscan’tincludeopaquetypes.Classescan’tuseanopaquetypeasthereturntypeofanonfinalmethod.

Afunctionthatusesanopaquetypeasitsreturntypemustreturnvaluesthatshareasingleunderlyingtype.Thereturntypecanincludetypesthatarepartofthefunction’sgenerictypeparameters.Forexample,afunctionsomeFunction<T>()couldreturnavalueoftypeTorDictionary<String,T>.

GRAMMAR OF AN OPAQUE TYPE

opaque-type → some type

MetatypeType

Ametatypetypereferstothetypeofanytype,includingclasstypes,structuretypes,enumerationtypes,andprotocoltypes.

Themetatypeofaclass,structure,orenumerationtypeisthenameofthattypefollowedby.Type.Themetatypeofaprotocoltype—nottheconcretetypethatconformstotheprotocolatruntime—isthenameofthatprotocolfollowedby.Protocol.Forexample,themetatypeoftheclasstypeSomeClassisSomeClass.TypeandthemetatypeoftheprotocolSomeProtocolisSomeProtocol.Protocol.

Youcanusethepostfixselfexpressiontoaccessatypeasavalue.Forexample,SomeClass.selfreturnsSomeClassitself,notaninstanceofSomeClass.AndSomeProtocol.selfreturnsSomeProtocolitself,notaninstanceofatypethatconformstoSomeProtocolatruntime.Youcancallthetype(of:)functionwith

Page 566: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

aninstanceofatypetoaccessthatinstance’sdynamic,runtimetypeasavalue,asthefollowingexampleshows:

1 classSomeBaseClass{

2 classfuncprintClassName(){

3 print("SomeBaseClass")

4 }

5 }

6 classSomeSubClass:SomeBaseClass{

7 overrideclassfuncprintClassName(){

8 print("SomeSubClass")

9 }

10 }

11 letsomeInstance:SomeBaseClass=SomeSubClass()

12 //Thecompile-timetypeofsomeInstanceisSomeBaseClass,

13 //andtheruntimetypeofsomeInstanceisSomeSubClass

14 type(of:someInstance).printClassName()

15 //Prints"SomeSubClass"

Formoreinformation,seetype(of:)intheSwiftstandardlibrary.

Useaninitializerexpressiontoconstructaninstanceofatypefromthattype’smetatypevalue.Forclassinstances,theinitializerthat’scalledmustbemarkedwiththerequiredkeywordortheentireclassmarkedwiththefinalkeyword.

1 classAnotherSubClass:SomeBaseClass{

2 letstring:String

3 requiredinit(string:String){

4 self.string=string

5 }

6 overrideclassfuncprintClassName(){

7 print("AnotherSubClass")

Page 567: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 }

9 }

10 letmetatype:AnotherSubClass.Type=AnotherSubClass.self

11 letanotherInstance=metatype.init(string:"somestring")

GRAMMAR OF AMETATYPE TYPE

metatype-type → type . Type | type . Protocol

SelfType

TheSelftypeisn’taspecifictype,butratherletsyouconvenientlyrefertothecurrenttypewithoutrepeatingorknowingthattype’sname.

Inaprotocoldeclarationoraprotocolmemberdeclaration,theSelftypereferstotheeventualtypethatconformstotheprotocol.

Inastructure,class,orenumerationdeclaration,theSelftypereferstothetypeintroducedbythedeclaration.Insidethedeclarationforamemberofatype,theSelftypereferstothattype.Inthemembersofaclassdeclaration,Selfcanappearasthereturntypeofamethodandinthebodyofamethod,butnotinanyothercontext.Forexample,thecodebelowshowsaninstancemethodfwhosereturntypeisSelf.

1 classSuperclass{

2 funcf()->Self{returnself}

3 }

4 letx=Superclass()

5 print(type(of:x.f()))

6 //Prints"Superclass"

7

8 classSubclass:Superclass{}

9 lety=Subclass()

Page 568: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

10 print(type(of:y.f()))

11 //Prints"Subclass"

12

13 letz:Superclass=Subclass()

14 print(type(of:z.f()))

15 //Prints"Subclass"

ThelastpartoftheexampleaboveshowsthatSelfreferstotheruntimetypeSubclassofthevalueofz,notthecompile-timetypeSuperclassofthevariableitself.

Insideanestedtypedeclaration,theSelftypereferstothetypeintroducedbytheinnermosttypedeclaration.

TheSelftypereferstothesametypeasthetype(of:)functionintheSwiftstandardlibrary.WritingSelf.someStaticMembertoaccessamemberofthecurrenttypeisthesameaswritingtype(of:self).someStaticMember.

GRAMMAR OF A SELF TYPE

self-type → Self

TypeInheritanceClause

Atypeinheritanceclauseisusedtospecifywhichclassanamedtypeinheritsfromandwhichprotocolsanamedtypeconformsto.Atypeinheritanceclausebeginswithacolon(:),followedbyalistoftypeidentifiers.

Classtypescaninheritfromasinglesuperclassandconformtoanynumberofprotocols.Whendefiningaclass,thenameofthesuperclassmustappearfirstinthelistoftypeidentifiers,followedbyanynumberofprotocolstheclassmustconformto.Iftheclassdoesn’tinheritfromanotherclass,thelistcanbeginwithaprotocolinstead.Foranextendeddiscussionandseveralexamplesofclassinheritance,seeInheritance.

Page 569: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Othernamedtypescanonlyinheritfromorconformtoalistofprotocols.Protocoltypescaninheritfromanynumberofotherprotocols.Whenaprotocoltypeinheritsfromotherprotocols,thesetofrequirementsfromthoseotherprotocolsareaggregatedtogether,andanytypethatinheritsfromthecurrentprotocolmustconformtoallofthoserequirements.

Atypeinheritanceclauseinanenumerationdefinitioncanbeeitheralistofprotocols,orinthecaseofanenumerationthatassignsrawvaluestoitscases,asingle,namedtypethatspecifiesthetypeofthoserawvalues.Foranexampleofanenumerationdefinitionthatusesatypeinheritanceclausetospecifythetypeofitsrawvalues,seeRawValues.

GRAMMAR OF ATYPE I NHER I TANCE CLAUSE

type-inheritance-clause → : type-inheritance-listtype-inheritance-list → type-identifier | type-identifier , type-inheritance-list

TypeInference

Swiftusestypeinferenceextensively,allowingyoutoomitthetypeorpartofthetypeofmanyvariablesandexpressionsinyourcode.Forexample,insteadofwritingvarx:Int=0,youcanwritevarx=0,omittingthetypecompletely—thecompilercorrectlyinfersthatxnamesavalueoftypeInt.Similarly,youcanomitpartofatypewhenthefulltypecanbeinferredfromcontext.Forexample,ifyouwriteletdict:Dictionary=["A":1],thecompilerinfersthatdicthasthetypeDictionary<String,Int>.

Inbothoftheexamplesabove,thetypeinformationispassedupfromtheleavesoftheexpressiontreetoitsroot.Thatis,thetypeofxinvarx:Int=0isinferredbyfirstcheckingthetypeof0andthenpassingthistypeinformationuptotheroot(thevariablex).

InSwift,typeinformationcanalsoflowintheoppositedirection—fromtherootdowntotheleaves.Inthefollowingexample,forinstance,theexplicittypeannotation(:Float)ontheconstanteFloatcausesthenumericliteral2.71828tohaveaninferredtypeofFloatinsteadofDouble.

Page 570: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 lete=2.71828//ThetypeofeisinferredtobeDouble.

2 leteFloat:Float=2.71828//ThetypeofeFloatisFloat.

TypeinferenceinSwiftoperatesatthelevelofasingleexpressionorstatement.Thismeansthatalloftheinformationneededtoinferanomittedtypeorpartofatypeinanexpressionmustbeaccessiblefromtype-checkingtheexpressionoroneofitssubexpressions.

Page 571: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Expressions

InSwift,therearefourkindsofexpressions:prefixexpressions,binaryexpressions,primaryexpressions,andpostfixexpressions.Evaluatinganexpressionreturnsavalue,causesasideeffect,orboth.

Prefixandbinaryexpressionsletyouapplyoperatorstosmallerexpressions.Primaryexpressionsareconceptuallythesimplestkindofexpression,andtheyprovideawaytoaccessvalues.Postfixexpressions,likeprefixandbinaryexpressions,letyoubuildupmorecomplexexpressionsusingpostfixessuchasfunctioncallsandmemberaccess.Eachkindofexpressionisdescribedindetailinthesectionsbelow.

GRAMMAR OF AN EXPRESS ION

expression → try-operator opt prefix-expression binary-expressions optexpression-list → expression | expression , expression-list

PrefixExpressions

Prefixexpressionscombineanoptionalprefixoperatorwithanexpression.Prefixoperatorstakeoneargument,theexpressionthatfollowsthem.

Forinformationaboutthebehavioroftheseoperators,seeBasicOperatorsandAdvancedOperators.

ForinformationabouttheoperatorsprovidedbytheSwiftstandardlibrary,seeOperatorDeclarations.

Inadditiontothestandardlibraryoperators,youuse&immediatelybeforethenameofavariablethat’sbeingpassedasanin-outargumenttoafunctioncallexpression.Formoreinformationandtoseeanexample,seeIn-OutParameters.

GRAMMAR OF A PREF IX EXPRESS ION

prefix-expression → prefix-operator opt postfix-expression

Page 572: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

prefix-expression → in-out-expressionin-out-expression → & identifier

TryOperatorAtryexpressionconsistsofthetryoperatorfollowedbyanexpressionthatcanthrowanerror.Ithasthefollowingform:

try expression

Anoptional-tryexpressionconsistsofthetry?operatorfollowedbyanexpressionthatcanthrowanerror.Ithasthefollowingform:

try? expression

Iftheexpressiondoesnotthrowanerror,thevalueoftheoptional-tryexpressionisanoptionalcontainingthevalueoftheexpression.Otherwise,thevalueoftheoptional-tryexpressionisnil.

Aforced-tryexpressionconsistsofthetry!operatorfollowedbyanexpressionthatcanthrowanerror.Ithasthefollowingform:

try! expression

Iftheexpressionthrowsanerror,aruntimeerrorisproduced.

Whentheexpressionontheleft-handsideofabinaryoperatorismarkedwithtry,try?,ortry!,thatoperatorappliestothewholebinaryexpression.Thatsaid,youcanuseparenthesestobeexplicitaboutthescopeoftheoperator’sapplication.

1 sum=trysomeThrowingFunction()+anotherThrowingFunction()

//tryappliestobothfunctioncalls

2 sum=try(someThrowingFunction()+anotherThrowingFunction())

//tryappliestobothfunctioncalls

Page 573: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 sum=(trysomeThrowingFunction())+anotherThrowingFunction()

//Error:tryappliesonlytothefirstfunctioncall

Atryexpressioncan’tappearontheright-handsideofabinaryoperator,unlessthebinaryoperatoristheassignmentoperatororthetryexpressionisenclosedinparentheses.

Formoreinformationandtoseeexamplesofhowtousetry,try?,andtry!,seeErrorHandling.

GRAMMAR OF ATRY EXPRESS ION

try-operator → try | try ? | try !

BinaryExpressions

Binaryexpressionscombineaninfixbinaryoperatorwiththeexpressionthatittakesasitsleft-handandright-handarguments.Ithasthefollowingform:

left-handargument operator right-handargument

Forinformationaboutthebehavioroftheseoperators,seeBasicOperatorsandAdvancedOperators.

ForinformationabouttheoperatorsprovidedbytheSwiftstandardlibrary,seeOperatorDeclarations.

NOTE

Atparsetime,anexpressionmadeupofbinaryoperatorsisrepresentedasaflatlist.Thislististransformedintoatreebyapplyingoperatorprecedence.Forexample,theexpression2+3*5isinitiallyunderstoodasaflatlistoffiveitems,2,+,3,*,and5.Thisprocesstransformsitintothetree(2+(3*5)).

GRAMMAR OF A B INARY EXPRESS ION

binary-expression → binary-operator prefix-expressionbinary-expression → assignment-operator try-operator opt prefix-expression

Page 574: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

binary-expression → conditional-operator try-operator opt prefix-expressionbinary-expression → type-casting-operatorbinary-expressions → binary-expression binary-expressions opt

AssignmentOperatorTheassignmentoperatorsetsanewvalueforagivenexpression.Ithasthefollowingform:

expression = value

Thevalueoftheexpressionissettothevalueobtainedbyevaluatingthevalue.Iftheexpressionisatuple,thevaluemustbeatuplewiththesamenumberofelements.(Nestedtuplesareallowed.)Assignmentisperformedfromeachpartofthevaluetothecorrespondingpartoftheexpression.Forexample:

1 (a,_,(b,c))=("test",9.45,(12,3))

2 //ais"test",bis12,cis3,and9.45isignored

Theassignmentoperatordoesnotreturnanyvalue.

GRAMMAR OF AN ASS IGNMENT OPERATOR

assignment-operator → =

TernaryConditionalOperatorTheternaryconditionaloperatorevaluatestooneoftwogivenvaluesbasedonthevalueofacondition.Ithasthefollowingform:

condition ? expressionusediftrue :

expressionusediffalse

Iftheconditionevaluatestotrue,theconditionaloperatorevaluatesthefirstexpressionandreturnsitsvalue.Otherwise,itevaluatesthesecondexpression

Page 575: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

andreturnsitsvalue.Theunusedexpressionisnotevaluated.

Foranexamplethatusestheternaryconditionaloperator,seeTernaryConditionalOperator.

GRAMMAR OF ACOND I T IONALOPERATOR

conditional-operator → ? expression :

Type-CastingOperatorsTherearefourtype-castingoperators:theisoperator,theasoperator,theas?operator,andtheas!operator.

Theyhavethefollowingform:

expression is type

expression as type

expression as? type

expression as! type

Theisoperatorchecksatruntimewhethertheexpressioncanbecasttothespecifiedtype.Itreturnstrueiftheexpressioncanbecasttothespecifiedtype;otherwise,itreturnsfalse.

Theasoperatorperformsacastwhenitisknownatcompiletimethatthecastalwayssucceeds,suchasupcastingorbridging.Upcastingletsyouuseanexpressionasaninstanceofitstype’ssupertype,withoutusinganintermediatevariable.Thefollowingapproachesareequivalent:

1 funcf(_any:Any){print("FunctionforAny")}

2 funcf(_int:Int){print("FunctionforInt")}

3 letx=10

4 f(x)

5 //Prints"FunctionforInt"

Page 576: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6

7 lety:Any=x

8 f(y)

9 //Prints"FunctionforAny"

10

11 f(xasAny)

12 //Prints"FunctionforAny"

BridgingletsyouuseanexpressionofaSwiftstandardlibrarytypesuchasStringasitscorrespondingFoundationtypesuchasNSStringwithoutneedingtocreateanewinstance.Formoreinformationonbridging,seeWorkingwithFoundationTypes.

Theas?operatorperformsaconditionalcastoftheexpressiontothespecifiedtype.Theas?operatorreturnsanoptionalofthespecifiedtype.Atruntime,ifthecastsucceeds,thevalueofexpressioniswrappedinanoptionalandreturned;otherwise,thevaluereturnedisnil.Ifcastingtothespecifiedtypeisguaranteedtofailorisguaranteedtosucceed,acompile-timeerrorisraised.

Theas!operatorperformsaforcedcastoftheexpressiontothespecifiedtype.Theas!operatorreturnsavalueofthespecifiedtype,notanoptionaltype.Ifthecastfails,aruntimeerrorisraised.Thebehaviorofxas!Tisthesameasthebehaviorof(xas?T)!.

Formoreinformationabouttypecastingandtoseeexamplesthatusethetype-castingoperators,seeTypeCasting.

GRAMMAR OF ATYPE -CAST ING OPERATOR

type-casting-operator → is typetype-casting-operator → as typetype-casting-operator → as ? typetype-casting-operator → as ! type

PrimaryExpressions

Page 577: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Primaryexpressionsarethemostbasickindofexpression.Theycanbeusedasexpressionsontheirown,andtheycanbecombinedwithothertokenstomakeprefixexpressions,binaryexpressions,andpostfixexpressions.

GRAMMAR OF A PR IMARY EXPRESS ION

primary-expression → identifier generic-argument-clause optprimary-expression → literal-expressionprimary-expression → self-expressionprimary-expression → superclass-expressionprimary-expression → closure-expressionprimary-expression → parenthesized-expressionprimary-expression → tuple-expressionprimary-expression → implicit-member-expressionprimary-expression → wildcard-expressionprimary-expression → key-path-expressionprimary-expression → selector-expressionprimary-expression → key-path-string-expression

LiteralExpressionAliteralexpressionconsistsofeitheranordinaryliteral(suchasastringoranumber),anarrayordictionaryliteral,aplaygroundliteral,oroneofthefollowingspecialliterals:

Literal Type Value

#file String Thenameofthefileinwhichitappears.

#line Int Thelinenumberonwhichitappears.

#column Int Thecolumnnumberinwhichitbegins.

#function String Thenameofthedeclarationinwhichitappears.

Page 578: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

#dsohandle UnsafeRawPointer TheDSO(dynamicsharedobject)handleinusewhereitappears.

Insideafunction,thevalueof#functionisthenameofthatfunction,insideamethoditisthenameofthatmethod,insideapropertygetterorsetteritisthenameofthatproperty,insidespecialmemberslikeinitorsubscriptitisthenameofthatkeyword,andatthetoplevelofafileitisthenameofthecurrentmodule.

Whenusedasthedefaultvalueofafunctionormethodparameter,thespecialliteral’svalueisdeterminedwhenthedefaultvalueexpressionisevaluatedatthecallsite.

1 funclogFunctionName(string:String=#function){

2 print(string)

3 }

4 funcmyFunction(){

5 logFunctionName()//Prints"myFunction()".

6 }

Anarrayliteralisanorderedcollectionofvalues.Ithasthefollowingform:

[ value1 , value2 , ... ]

Thelastexpressioninthearraycanbefollowedbyanoptionalcomma.Thevalueofanarrayliteralhastype[T],whereTisthetypeoftheexpressionsinsideit.Ifthereareexpressionsofmultipletypes,Tistheirclosestcommonsupertype.Emptyarrayliteralsarewrittenusinganemptypairofsquarebracketsandcanbeusedtocreateanemptyarrayofaspecifiedtype.

varemptyArray:[Double]=[]

Adictionaryliteralisanunorderedcollectionofkey-valuepairs.Ithasthefollowingform:

Page 579: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

[ key1 : value1 , key2 : value2 , ... ]

Thelastexpressioninthedictionarycanbefollowedbyanoptionalcomma.Thevalueofadictionaryliteralhastype[Key:Value],whereKeyisthetypeofitskeyexpressionsandValueisthetypeofitsvalueexpressions.Ifthereareexpressionsofmultipletypes,KeyandValuearetheclosestcommonsupertypefortheirrespectivevalues.Anemptydictionaryliteraliswrittenasacoloninsideapairofbrackets([:])todistinguishitfromanemptyarrayliteral.Youcanuseanemptydictionaryliteraltocreateanemptydictionaryliteralofspecifiedkeyandvaluetypes.

varemptyDictionary:[String:Double]=[:]

AplaygroundliteralisusedbyXcodetocreateaninteractiverepresentationofacolor,file,orimagewithintheprogrameditor.PlaygroundliteralsinplaintextoutsideofXcodearerepresentedusingaspecialliteralsyntax.

ForinformationonusingplaygroundliteralsinXcode,seeAddacolor,file,orimageliteralinXcodeHelp.

GRAMMAR OF A L I TERALEXPRESS ION

literal-expression → literalliteral-expression → array-literal | dictionary-literal | playground-literalliteral-expression → #file | #line | #column | #function | #dsohandlearray-literal → [ array-literal-items opt ]array-literal-items → array-literal-item ,opt | array-literal-item , array-literal-itemsarray-literal-item → expressiondictionary-literal → [ dictionary-literal-items ] | [ : ]dictionary-literal-items → dictionary-literal-item ,opt | dictionary-literal-item , dictionary-

literal-itemsdictionary-literal-item → expression : expressionplayground-literal → #colorLiteral ( red : expression , green : expression

, blue : expression , alpha : expression )playground-literal → #fileLiteral ( resourceName : expression )playground-literal → #imageLiteral ( resourceName : expression )

SelfExpression

Page 580: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theselfexpressionisanexplicitreferencetothecurrenttypeorinstanceofthetypeinwhichitoccurs.Ithasthefollowingforms:

self

self. membername

self[ subscriptindex ]

self( initializerarguments )

self.init( initializerarguments )

Inaninitializer,subscript,orinstancemethod,selfreferstothecurrentinstanceofthetypeinwhichitoccurs.Inatypemethod,selfreferstothecurrenttypeinwhichitoccurs.

Theselfexpressionisusedtospecifyscopewhenaccessingmembers,providingdisambiguationwhenthereisanothervariableofthesamenameinscope,suchasafunctionparameter.Forexample:

1 classSomeClass{

2 vargreeting:String

3 init(greeting:String){

4 self.greeting=greeting

5 }

6 }

Inamutatingmethodofavaluetype,youcanassignanewinstanceofthatvaluetypetoself.Forexample:

1 structPoint{

2 varx=0.0,y=0.0

3 mutatingfuncmoveBy(xdeltaX:Double,ydeltaY:Double){

4 self=Point(x:x+deltaX,y:y+deltaY)

5 }

6 }

Page 581: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF A SELF EXPRESS ION

self-expression → self | self-method-expression | self-subscript-expression | self-initializer-expression

self-method-expression → self . identifierself-subscript-expression → self [ function-call-argument-list ]self-initializer-expression → self . init

SuperclassExpressionAsuperclassexpressionletsaclassinteractwithitssuperclass.Ithasoneofthefollowingforms:

super. membername

super[ subscriptindex ]

super.init( initializerarguments )

Thefirstformisusedtoaccessamemberofthesuperclass.Thesecondformisusedtoaccessthesuperclass’ssubscriptimplementation.Thethirdformisusedtoaccessaninitializerofthesuperclass.

Subclassescanuseasuperclassexpressionintheirimplementationofmembers,subscripting,andinitializerstomakeuseoftheimplementationintheirsuperclass.

GRAMMAR OF A SUPERCLASS EXPRESS ION

superclass-expression → superclass-method-expression | superclass-subscript-expression | superclass-initializer-expression

superclass-method-expression → super . identifiersuperclass-subscript-expression → super [ function-call-argument-list ]superclass-initializer-expression → super . init

ClosureExpressionAclosureexpressioncreatesaclosure,alsoknownasalambdaorananonymousfunctioninotherprogramminglanguages.Likeafunctiondeclaration,aclosurecontainsstatements,anditcapturesconstantsandvariablesfromitsenclosing

Page 582: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

scope.Ithasthefollowingform:

{( parameters )-> returntype in

statements

}

Theparametershavethesameformastheparametersinafunctiondeclaration,asdescribedinFunctionDeclaration.

Thereareseveralspecialformsthatallowclosurestobewrittenmoreconcisely:

Aclosurecanomitthetypesofitsparameters,itsreturntype,orboth.Ifyouomittheparameternamesandbothtypes,omittheinkeywordbeforethestatements.Iftheomittedtypescan’tbeinferred,acompile-timeerrorisraised.

Aclosuremayomitnamesforitsparameters.Itsparametersarethenimplicitlynamed$followedbytheirposition:$0,$1,$2,andsoon.

Aclosurethatconsistsofonlyasingleexpressionisunderstoodtoreturnthevalueofthatexpression.Thecontentsofthisexpressionarealsoconsideredwhenperformingtypeinferenceonthesurroundingexpression.

Thefollowingclosureexpressionsareequivalent:

1 myFunction{(x:Int,y:Int)->Intin

2 returnx+y

3 }

4

5 myFunction{x,yin

6 returnx+y

7 }

8

9 myFunction{return$0+$1}

10

Page 583: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

11 myFunction{$0+$1}

Forinformationaboutpassingaclosureasanargumenttoafunction,seeFunctionCallExpression.

Closureexpressionscanbeusedwithoutbeingstoredinavariableorconstant,suchaswhenyouimmediatelyuseaclosureaspartofafunctioncall.TheclosureexpressionspassedtomyFunctionincodeaboveareexamplesofthiskindofimmediateuse.Asaresult,whetheraclosureexpressionisescapingornonescapingdependsonthesurroundingcontextoftheexpression.Aclosureexpressionisnonescapingifitiscalledimmediatelyorpassedasanonescapingfunctionargument.Otherwise,theclosureexpressionisescaping.

Formoreinformationaboutescapingclosures,seeEscapingClosures.

CaptureLists

Bydefault,aclosureexpressioncapturesconstantsandvariablesfromitssurroundingscopewithstrongreferencestothosevalues.Youcanuseacapturelisttoexplicitlycontrolhowvaluesarecapturedinaclosure.

Acapturelistiswrittenasacomma-separatedlistofexpressionssurroundedbysquarebrackets,beforethelistofparameters.Ifyouuseacapturelist,youmustalsousetheinkeyword,evenifyouomittheparameternames,parametertypes,andreturntype.

Theentriesinthecapturelistareinitializedwhentheclosureiscreated.Foreachentryinthecapturelist,aconstantisinitializedtothevalueoftheconstantorvariablethathasthesamenameinthesurroundingscope.Forexampleinthecodebelow,aisincludedinthecapturelistbutbisnot,whichgivesthemdifferentbehavior.

1 vara=0

2 varb=0

3 letclosure={[a]in

4 print(a,b)

Page 584: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 }

6

7 a=10

8 b=10

9 closure()

10 //Prints"010"

Therearetwodifferentthingsnameda,thevariableinthesurroundingscopeandtheconstantintheclosure’sscope,butonlyonevariablenamedb.Theaintheinnerscopeisinitializedwiththevalueoftheaintheouterscopewhentheclosureiscreated,buttheirvaluesarenotconnectedinanyspecialway.Thismeansthatachangetothevalueofaintheouterscopedoesnotaffectthevalueofaintheinnerscope,nordoesachangetoainsidetheclosureaffectthevalueofaoutsidetheclosure.Incontrast,thereisonlyonevariablenamedb—thebintheouterscope—sochangesfrominsideoroutsidetheclosurearevisibleinbothplaces.

Thisdistinctionisnotvisiblewhenthecapturedvariable’stypehasreferencesemantics.Forexample,therearetwothingsnamedxinthecodebelow,avariableintheouterscopeandaconstantintheinnerscope,buttheybothrefertothesameobjectbecauseofreferencesemantics.

1 classSimpleClass{

2 varvalue:Int=0

3 }

4 varx=SimpleClass()

5 vary=SimpleClass()

6 letclosure={[x]in

7 print(x.value,y.value)

8 }

9

10 x.value=10

11 y.value=10

Page 585: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

12 closure()

13 //Prints"1010"

Ifthetypeoftheexpression’svalueisaclass,youcanmarktheexpressioninacapturelistwithweakorunownedtocaptureaweakorunownedreferencetotheexpression’svalue.

1 myFunction{print(self.title)}//implicit

strongcapture

2 myFunction{[self]inprint(self.title)}//explicit

strongcapture

3 myFunction{[weakself]inprint(self!.title)}//weak

capture

4 myFunction{[unownedself]inprint(self.title)}//unowned

capture

Youcanalsobindanarbitraryexpressiontoanamedvalueinacapturelist.Theexpressionisevaluatedwhentheclosureiscreated,andthevalueiscapturedwiththespecifiedstrength.Forexample:

1 //Weakcaptureof"self.parent"as"parent"

2 myFunction{[weakparent=self.parent]in

print(parent!.title)}

Formoreinformationandexamplesofclosureexpressions,seeClosureExpressions.Formoreinformationandexamplesofcapturelists,seeResolvingStrongReferenceCyclesforClosures.

GRAMMAR OF ACLOSURE EXPRESS ION

closure-expression → { closure-signature opt statements opt }closure-signature → capture-list opt closure-parameter-clause throwsopt function-

result opt inclosure-signature → capture-list inclosure-parameter-clause → ( ) | ( closure-parameter-list ) | identifier-listclosure-parameter-list → closure-parameter | closure-parameter , closure-parameter-

Page 586: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

listclosure-parameter → closure-parameter-name type-annotation optclosure-parameter → closure-parameter-name type-annotation ...closure-parameter-name → identifiercapture-list → [ capture-list-items ]capture-list-items → capture-list-item | capture-list-item , capture-list-itemscapture-list-item → capture-specifier opt expressioncapture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

ImplicitMemberExpressionAnimplicitmemberexpressionisanabbreviatedwaytoaccessamemberofatype,suchasanenumerationcaseoratypemethod,inacontextwheretypeinferencecandeterminetheimpliedtype.Ithasthefollowingform:

. membername

Forexample:

1 varx=MyEnumeration.someValue

2 x=.anotherValue

GRAMMAR OF A IMPL IC I T MEMBER EXPRESS ION

implicit-member-expression → . identifier

ParenthesizedExpressionAparenthesizedexpressionconsistsofanexpressionsurroundedbyparentheses.Youcanuseparenthesestospecifytheprecedenceofoperationsbyexplicitlygroupingexpressions.Groupingparenthesesdon’tchangeanexpression’stype—forexample,thetypeof(1)issimplyInt.

GRAMMAR OF A PARENTHES I ZED EXPRESS ION

parenthesized-expression → ( expression )

Page 587: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TupleExpressionAtupleexpressionconsistsofacomma-separatedlistofexpressionssurroundedbyparentheses.Eachexpressioncanhaveanoptionalidentifierbeforeit,separatedbyacolon(:).Ithasthefollowingform:

( identifier1 : expression1 , identifier2 : expression2 ,

... )

Eachidentifierinatupleexpressionmustbeuniquewithinthescopeofthetupleexpression.Inanestedtupleexpression,identifiersatthesamelevelofnestingmustbeunique.Forexample,(a:10,a:20)isinvalidbecausethelabelaappearstwiceatthesamelevel.However,(a:10,b:(a:1,x:2))isvalid—althoughaappearstwice,itappearsonceintheoutertupleandonceintheinnertuple.

Atupleexpressioncancontainzeroexpressions,oritcancontaintwoormoreexpressions.Asingleexpressioninsideparenthesesisaparenthesizedexpression.

NOTE

Bothanemptytupleexpressionandanemptytupletypearewritten()inSwift.BecauseVoidisatypealiasfor(),youcanuseittowriteanemptytupletype.However,likealltypealiases,Voidisalwaysatype—youcan’tuseittowriteanemptytupleexpression.

GRAMMAR OF ATUPLE EXPRESS ION

tuple-expression → ( ) | ( tuple-element , tuple-element-list )tuple-element-list → tuple-element | tuple-element , tuple-element-listtuple-element → expression | identifier : expression

WildcardExpressionAwildcardexpressionisusedtoexplicitlyignoreavalueduringanassignment.Forexample,inthefollowingassignment10isassignedtoxand20isignored:

1 (x,_)=(10,20)

Page 588: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 //xis10,and20isignored

GRAMMAR OF AW I LDCARD EXPRESS ION

wildcard-expression → _

Key-PathExpressionAkey-pathexpressionreferstoapropertyorsubscriptofatype.Youusekey-pathexpressionsindynamicprogrammingtasks,suchaskey-valueobserving.Theyhavethefollowingform:

\ typename . path

Thetypenameisthenameofaconcretetype,includinganygenericparameters,suchasString,[Int],orSet<Int>.

Thepathconsistsofpropertynames,subscripts,optional-chainingexpressions,andforcedunwrappingexpressions.Eachofthesekey-pathcomponentscanberepeatedasmanytimesasneeded,inanyorder.

Atcompiletime,akey-pathexpressionisreplacedbyaninstanceoftheKeyPathclass.

Toaccessavalueusingakeypath,passthekeypathtothesubscript(keyPath:)subscript,whichisavailableonalltypes.Forexample:

1 structSomeStructure{

2 varsomeValue:Int

3 }

4

5 lets=SomeStructure(someValue:12)

6 letpathToProperty=\SomeStructure.someValue

7

8 letvalue=s[keyPath:pathToProperty]

Page 589: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 //valueis12

Thetypenamecanbeomittedincontextswheretypeinferencecandeterminetheimpliedtype.Thefollowingcodeuses\.somePropertyinsteadof\SomeClass.someProperty:

1 classSomeClass:NSObject{

2 @objcvarsomeProperty:Int

3 init(someProperty:Int){

4 self.someProperty=someProperty

5 }

6 }

7

8 letc=SomeClass(someProperty:10)

9 c.observe(\.someProperty){object,changein

10 //...

11 }

Thepathcanrefertoselftocreatetheidentitykeypath(\.self).Theidentitykeypathreferstoawholeinstance,soyoucanuseittoaccessandchangeallofthedatastoredinavariableinasinglestep.Forexample:

1 varcompoundValue=(a:1,b:2)

2 //EquivalenttocompoundValue=(a:10,b:20)

3 compoundValue[keyPath:\.self]=(a:10,b:20)

Thepathcancontainmultiplepropertynames,separatedbyperiods,torefertoapropertyofaproperty’svalue.Thiscodeusesthekeypathexpression\OuterStructure.outer.someValuetoaccessthesomeValuepropertyoftheOuterStructuretype’souterproperty:

1 structOuterStructure{

2 varouter:SomeStructure

Page 590: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

3 init(someValue:Int){

4 self.outer=SomeStructure(someValue:someValue)

5 }

6 }

7

8 letnested=OuterStructure(someValue:24)

9 letnestedKeyPath=\OuterStructure.outer.someValue

10

11 letnestedValue=nested[keyPath:nestedKeyPath]

12 //nestedValueis24

Thepathcanincludesubscriptsusingbrackets,aslongasthesubscript’sparametertypeconformstotheHashableprotocol.Thisexampleusesasubscriptinakeypathtoaccessthesecondelementofanarray:

1 letgreetings=["hello","hola","bonjour","" ]

2 letmyGreeting=greetings[keyPath:\[String].[1]]

3 //myGreetingis'hola'

Thevalueusedinasubscriptcanbeanamedvalueoraliteral.Valuesarecapturedinkeypathsusingvaluesemantics.Thefollowingcodeusesthevariableindexinbothakey-pathexpressionandinaclosuretoaccessthethirdelementofthegreetingsarray.Whenindexismodified,thekey-pathexpressionstillreferencesthethirdelement,whiletheclosureusesthenewindex.

1 varindex=2

2 letpath=\[String].[index]

3 letfn:([String])->String={stringsinstrings[index]}

4

5 print(greetings[keyPath:path])

6 //Prints"bonjour"

7 print(fn(greetings))

Page 591: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

8 //Prints"bonjour"

9

10 //Setting'index'toanewvaluedoesn'taffect'path'

11 index+=1

12 print(greetings[keyPath:path])

13 //Prints"bonjour"

14

15 //Because'fn'closesover'index',itusesthenewvalue

16 print(fn(greetings))

17 //Prints""

Thepathcanuseoptionalchainingandforcedunwrapping.Thiscodeusesoptionalchaininginakeypathtoaccessapropertyofanoptionalstring:

1 letfirstGreeting:String?=greetings.first

2 print(firstGreeting?.countasAny)

3 //Prints"Optional(5)"

4

5 //Dothesamethingusingakeypath.

6 letcount=greetings[keyPath:\[String].first?.count]

7 print(countasAny)

8 //Prints"Optional(5)"

Youcanmixandmatchcomponentsofkeypathstoaccessvaluesthataredeeplynestedwithinatype.Thefollowingcodeaccessesdifferentvaluesandpropertiesofadictionaryofarraysbyusingkey-pathexpressionsthatcombinethesecomponents.

1 letinterestingNumbers=["prime":[2,3,5,7,11,13,17],

2 "triangular":[1,3,6,10,15,21,

28],

3 "hexagonal":[1,6,15,28,45,66,

Page 592: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

91]]

4 print(interestingNumbers[keyPath:\[String:[Int]].["prime"]]

asAny)

5 //Prints"Optional([2,3,5,7,11,13,17])"

6 print(interestingNumbers[keyPath:\[String:[Int]].["prime"]!

[0]])

7 //Prints"2"

8 print(interestingNumbers[keyPath:\[String:[Int]].

["hexagonal"]!.count])

9 //Prints"7"

10 print(interestingNumbers[keyPath:\[String:[Int]].

["hexagonal"]!.count.bitWidth])

11 //Prints"64"

FormoreinformationaboutusingkeypathsincodethatinteractswithObjective-CAPIs,seeUsingObjective-CRuntimeFeaturesinSwift.Forinformationaboutkey-valuecodingandkey-valueobserving,seeKey-ValueCodingProgrammingGuideandKey-ValueObservingProgrammingGuide.

GRAMMAR OF A KEY-PATH EXPRESS ION

key-path-expression → \ type opt . key-path-componentskey-path-components → key-path-component | key-path-component . key-path-

componentskey-path-component → identifier key-path-postfixes opt | key-path-postfixeskey-path-postfixes → key-path-postfix key-path-postfixes optkey-path-postfix → ? | ! | self | [ function-call-argument-list ]

SelectorExpressionAselectorexpressionletsyouaccesstheselectorusedtorefertoamethodortoaproperty’sgetterorsetterinObjective-C.Ithasthefollowingform:

#selector( methodname )

Page 593: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

#selector(getter: propertyname )

#selector(setter: propertyname )

ThemethodnameandpropertynamemustbeareferencetoamethodorapropertythatisavailableintheObjective-Cruntime.ThevalueofaselectorexpressionisaninstanceoftheSelectortype.Forexample:

1 classSomeClass:NSObject{

2 @objcletproperty:String

3 @objc(doSomethingWithInt:)

4 funcdoSomething(_x:Int){}

5

6 init(property:String){

7 self.property=property

8 }

9 }

10 letselectorForMethod=#selector(SomeClass.doSomething(_:))

11 letselectorForPropertyGetter=#selector(getter:

SomeClass.property)

Whencreatingaselectorforaproperty’sgetter,thepropertynamecanbeareferencetoavariableorconstantproperty.Incontrast,whencreatingaselectorforaproperty’ssetter,thepropertynamemustbeareferencetoavariablepropertyonly.

Themethodnamecancontainparenthesesforgrouping,aswelltheasoperatortodisambiguatebetweenmethodsthatshareanamebuthavedifferenttypesignatures.Forexample:

1 extensionSomeClass{

2 @objc(doSomethingWithString:)

3 funcdoSomething(_x:String){}

4 }

Page 594: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 letanotherSelector=#selector(SomeClass.doSomething(_:)as

(SomeClass)->(String)->Void)

Becauseaselectoriscreatedatcompiletime,notatruntime,thecompilercancheckthatamethodorpropertyexistsandthatthey’reexposedtotheObjective-Cruntime.

NOTE

Althoughthemethodnameandthepropertynameareexpressions,they’reneverevaluated.

FormoreinformationaboutusingselectorsinSwiftcodethatinteractswithObjective-CAPIs,seeUsingObjective-CRuntimeFeaturesinSwift.

GRAMMAR OF A SELECTOR EXPRESS ION

selector-expression → #selector ( expression )selector-expression → #selector ( getter: expression )selector-expression → #selector ( setter: expression )

Key-PathStringExpressionAkey-pathstringexpressionletsyouaccessthestringusedtorefertoapropertyinObjective-C,foruseinkey-valuecodingandkey-valueobservingAPIs.Ithasthefollowingform:

#keyPath( propertyname )

ThepropertynamemustbeareferencetoapropertythatisavailableintheObjective-Cruntime.Atcompiletime,thekey-pathstringexpressionisreplacedbyastringliteral.Forexample:

1 classSomeClass:NSObject{

2 @objcvarsomeProperty:Int

3 init(someProperty:Int){

4 self.someProperty=someProperty

Page 595: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 }

6 }

7

8 letc=SomeClass(someProperty:12)

9 letkeyPath=#keyPath(SomeClass.someProperty)

10

11 ifletvalue=c.value(forKey:keyPath){

12 print(value)

13 }

14 //Prints"12"

Whenyouuseakey-pathstringexpressionwithinaclass,youcanrefertoapropertyofthatclassbywritingjustthepropertyname,withouttheclassname.

1 extensionSomeClass{

2 funcgetSomeKeyPath()->String{

3 return#keyPath(someProperty)

4 }

5 }

6 print(keyPath==c.getSomeKeyPath())

7 //Prints"true"

Becausethekeypathstringiscreatedatcompiletime,notatruntime,thecompilercancheckthatthepropertyexistsandthatthepropertyisexposedtotheObjective-Cruntime.

FormoreinformationaboutusingkeypathsinSwiftcodethatinteractswithObjective-CAPIs,seeUsingObjective-CRuntimeFeaturesinSwift.Forinformationaboutkey-valuecodingandkey-valueobserving,seeKey-ValueCodingProgrammingGuideandKey-ValueObservingProgrammingGuide.

NOTE

Althoughthepropertynameisanexpression,itisneverevaluated.

Page 596: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF A KEY-PATH STR ING EXPRESS ION

key-path-string-expression → #keyPath ( expression )

PostfixExpressions

Postfixexpressionsareformedbyapplyingapostfixoperatororotherpostfixsyntaxtoanexpression.Syntactically,everyprimaryexpressionisalsoapostfixexpression.

Forinformationaboutthebehavioroftheseoperators,seeBasicOperatorsandAdvancedOperators.

ForinformationabouttheoperatorsprovidedbytheSwiftstandardlibrary,seeOperatorDeclarations.

GRAMMAR OF A POSTF IX EXPRESS ION

postfix-expression → primary-expressionpostfix-expression → postfix-expression postfix-operatorpostfix-expression → function-call-expressionpostfix-expression → initializer-expressionpostfix-expression → explicit-member-expressionpostfix-expression → postfix-self-expressionpostfix-expression → subscript-expressionpostfix-expression → forced-value-expressionpostfix-expression → optional-chaining-expression

FunctionCallExpressionAfunctioncallexpressionconsistsofafunctionnamefollowedbyacomma-separatedlistofthefunction’sargumentsinparentheses.Functioncallexpressionshavethefollowingform:

functionname ( argumentvalue1 , argumentvalue2 )

Thefunctionnamecanbeanyexpressionwhosevalueisofafunctiontype.

Page 597: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Ifthefunctiondefinitionincludesnamesforitsparameters,thefunctioncallmustincludenamesbeforeitsargumentvaluesseparatedbyacolon(:).Thiskindoffunctioncallexpressionhasthefollowingform:

functionname ( argumentname1 : argumentvalue1 ,

argumentname2 : argumentvalue2 )

Afunctioncallexpressioncanincludeatrailingclosureintheformofaclosureexpressionimmediatelyaftertheclosingparenthesis.Thetrailingclosureisunderstoodasanargumenttothefunction,addedafterthelastparenthesizedargument.Thefollowingfunctioncallsareequivalent:

1 //someFunctiontakesanintegerandaclosureasitsarguments

2 someFunction(x:x,f:{$0==13})

3 someFunction(x:x){$0==13}

Ifthetrailingclosureisthefunction’sonlyargument,theparenthesescanbeomitted.

1 //someMethodtakesaclosureasitsonlyargument

2 myData.someMethod(){$0==13}

3 myData.someMethod{$0==13}

GRAMMAR OF A FUNCT ION CALL EXPRESS ION

function-call-expression → postfix-expression function-call-argument-clausefunction-call-expression → postfix-expression function-call-argument-clause opt trailing-

closurefunction-call-argument-clause → ( ) | ( function-call-argument-list )function-call-argument-list → function-call-argument | function-call-argument , function-

call-argument-listfunction-call-argument → expression | identifier : expressionfunction-call-argument → operator | identifier : operatortrailing-closure → closure-expression

InitializerExpression

Page 598: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Aninitializerexpressionprovidesaccesstoatype’sinitializer.Ithasthefollowingform:

expression .init( initializerarguments )

Youusetheinitializerexpressioninafunctioncallexpressiontoinitializeanewinstanceofatype.Youalsouseaninitializerexpressiontodelegatetotheinitializerofasuperclass.

1 classSomeSubClass:SomeSuperClass{

2 overrideinit(){

3 //subclassinitializationgoeshere

4 super.init()

5 }

6 }

Likeafunction,aninitializercanbeusedasavalue.Forexample:

1 //TypeannotationisrequiredbecauseStringhasmultiple

initializers.

2 letinitializer:(Int)->String=String.init

3 letoneTwoThree=[1,2,3].map(initializer).reduce("",+)

4 print(oneTwoThree)

5 //Prints"123"

Ifyouspecifyatypebyname,youcanaccessthetype’sinitializerwithoutusinganinitializerexpression.Inallothercases,youmustuseaninitializerexpression.

1 lets1=SomeType.init(data:3)//Valid

2 lets2=SomeType(data:1)//Alsovalid

3

4 lets3=type(of:someValue).init(data:7)//Valid

Page 599: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 lets4=type(of:someValue)(data:5)//Error

GRAMMAR OF AN I N I T I A L I ZER EXPRESS ION

initializer-expression → postfix-expression . initinitializer-expression → postfix-expression . init ( argument-names )

ExplicitMemberExpressionAnexplicitmemberexpressionallowsaccesstothemembersofanamedtype,atuple,oramodule.Itconsistsofaperiod(.)betweentheitemandtheidentifierofitsmember.

expression . membername

Themembersofanamedtypearenamedaspartofthetype’sdeclarationorextension.Forexample:

1 classSomeClass{

2 varsomeProperty=42

3 }

4 letc=SomeClass()

5 lety=c.someProperty//Memberaccess

Themembersofatupleareimplicitlynamedusingintegersintheordertheyappear,startingfromzero.Forexample:

1 vart=(10,20,30)

2 t.0=t.1

3 //Nowtis(20,20,30)

Themembersofamoduleaccessthetop-leveldeclarationsofthatmodule.

TypesdeclaredwiththedynamicMemberLookupattributeincludemembersthatarelookedupatruntime,asdescribedinAttributes.

Page 600: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Todistinguishbetweenmethodsorinitializerswhosenamesdifferonlybythenamesoftheirarguments,includetheargumentnamesinparentheses,witheachargumentnamefollowedbyacolon(:).Writeanunderscore(_)foranargumentwithnoname.Todistinguishbetweenoverloadedmethods,useatypeannotation.Forexample:

1 classSomeClass{

2 funcsomeMethod(x:Int,y:Int){}

3 funcsomeMethod(x:Int,z:Int){}

4 funcoverloadedMethod(x:Int,y:Int){}

5 funcoverloadedMethod(x:Int,y:Bool){}

6 }

7 letinstance=SomeClass()

8

9 leta=instance.someMethod//Ambiguous

10 letb=instance.someMethod(x:y:)//Unambiguous

11

12 letd=instance.overloadedMethod//Ambiguous

13 letd=instance.overloadedMethod(x:y:)//Stillambiguous

14 letd:(Int,Bool)->Void=instance.overloadedMethod(x:y:)

//Unambiguous

Ifaperiodappearsatthebeginningofaline,itisunderstoodaspartofanexplicitmemberexpression,notasanimplicitmemberexpression.Forexample,thefollowinglistingshowschainedmethodcallssplitoverseverallines:

1 letx=[10,3,20,15,4]

2 .sorted()

3 .filter{$0>5}

4 .map{$0*100}

GRAMMAR OF AN EXPL IC I T MEMBER EXPRESS ION

Page 601: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

explicit-member-expression → postfix-expression . decimal-digitsexplicit-member-expression → postfix-expression . identifier generic-argument-clause

optexplicit-member-expression → postfix-expression . identifier ( argument-names )argument-names → argument-name argument-names optargument-name → identifier :

PostfixSelfExpressionApostfixselfexpressionconsistsofanexpressionorthenameofatype,immediatelyfollowedby.self.Ithasthefollowingforms:

expression .self

type .self

Thefirstformevaluatestothevalueoftheexpression.Forexample,x.selfevaluatestox.

Thesecondformevaluatestothevalueofthetype.Usethisformtoaccessatypeasavalue.Forexample,becauseSomeClass.selfevaluatestotheSomeClasstypeitself,youcanpassittoafunctionormethodthatacceptsatype-levelargument.

GRAMMAR OF A POSTF IX SELF EXPRESS ION

postfix-self-expression → postfix-expression . self

SubscriptExpressionAsubscriptexpressionprovidessubscriptaccessusingthegetterandsetterofthecorrespondingsubscriptdeclaration.Ithasthefollowingform:

expression [ indexexpressions ]

Toevaluatethevalueofasubscriptexpression,thesubscriptgetterfortheexpression’stypeiscalledwiththeindexexpressionspassedasthesubscriptparameters.Tosetitsvalue,thesubscriptsetteriscalledinthesameway.

Page 602: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Forinformationaboutsubscriptdeclarations,seeProtocolSubscriptDeclaration.

GRAMMAR OF A SUBSCR IPT EXPRESS ION

subscript-expression → postfix-expression [ function-call-argument-list ]

Forced-ValueExpressionAforced-valueexpressionunwrapsanoptionalvaluethatyouarecertainisnotnil.Ithasthefollowingform:

expression !

Ifthevalueoftheexpressionisnotnil,theoptionalvalueisunwrappedandreturnedwiththecorrespondingnon-optionaltype.Otherwise,aruntimeerrorisraised.

Theunwrappedvalueofaforced-valueexpressioncanbemodified,eitherbymutatingthevalueitself,orbyassigningtooneofthevalue’smembers.Forexample:

1 varx:Int?=0

2 x!+=1

3 //xisnow1

4

5 varsomeDictionary=["a":[1,2,3],"b":[10,20]]

6 someDictionary["a"]![0]=100

7 //someDictionaryisnow["a":[100,2,3],"b":[10,20]]

GRAMMAR OF A FORCED -VALUE EXPRESS ION

forced-value-expression → postfix-expression !

Optional-ChainingExpression

Page 603: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Anoptional-chainingexpressionprovidesasimplifiedsyntaxforusingoptionalvaluesinpostfixexpressions.Ithasthefollowingform:

expression ?

Thepostfix?operatormakesanoptional-chainingexpressionfromanexpressionwithoutchangingtheexpression’svalue.

Optional-chainingexpressionsmustappearwithinapostfixexpression,andtheycausethepostfixexpressiontobeevaluatedinaspecialway.Ifthevalueoftheoptional-chainingexpressionisnil,alloftheotheroperationsinthepostfixexpressionareignoredandtheentirepostfixexpressionevaluatestonil.Ifthevalueoftheoptional-chainingexpressionisnotnil,thevalueoftheoptional-chainingexpressionisunwrappedandusedtoevaluatetherestofthepostfixexpression.Ineithercase,thevalueofthepostfixexpressionisstillofanoptionaltype.

Ifapostfixexpressionthatcontainsanoptional-chainingexpressionisnestedinsideotherpostfixexpressions,onlytheoutermostexpressionreturnsanoptionaltype.Intheexamplebelow,whencisnotnil,itsvalueisunwrappedandusedtoevaluate.property,thevalueofwhichisusedtoevaluate.performAction().Theentireexpressionc?.property.performAction()hasavalueofanoptionaltype.

1 varc:SomeClass?

2 varresult:Bool?=c?.property.performAction()

Thefollowingexampleshowsthebehavioroftheexampleabovewithoutusingoptionalchaining.

1 varresult:Bool?

2 ifletunwrappedC=c{

3 result=unwrappedC.property.performAction()

4 }

Theunwrappedvalueofanoptional-chainingexpressioncanbemodified,either

Page 604: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

bymutatingthevalueitself,orbyassigningtooneofthevalue’smembers.Ifthevalueoftheoptional-chainingexpressionisnil,theexpressionontheright-handsideoftheassignmentoperatorisnotevaluated.Forexample:

1 funcsomeFunctionWithSideEffects()->Int{

2 return42//Noactualsideeffects.

3 }

4 varsomeDictionary=["a":[1,2,3],"b":[10,20]]

5

6 someDictionary["nothere"]?[0]=someFunctionWithSideEffects()

7 //someFunctionWithSideEffectsisnotevaluated

8 //someDictionaryisstill["a":[1,2,3],"b":[10,20]]

9

10 someDictionary["a"]?[0]=someFunctionWithSideEffects()

11 //someFunctionWithSideEffectsisevaluatedandreturns42

12 //someDictionaryisnow["a":[42,2,3],"b":[10,20]]

GRAMMAR OF AN OPT IONAL -CHA IN ING EXPRESS ION

optional-chaining-expression → postfix-expression ?

Page 605: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Statements

InSwift,therearethreekindsofstatements:simplestatements,compilercontrolstatements,andcontrolflowstatements.Simplestatementsarethemostcommonandconsistofeitheranexpressionoradeclaration.Compilercontrolstatementsallowtheprogramtochangeaspectsofthecompiler’sbehaviorandincludeaconditionalcompilationblockandalinecontrolstatement.

Controlflowstatementsareusedtocontroltheflowofexecutioninaprogram.ThereareseveraltypesofcontrolflowstatementsinSwift,includingloopstatements,branchstatements,andcontroltransferstatements.Loopstatementsallowablockofcodetobeexecutedrepeatedly,branchstatementsallowacertainblockofcodetobeexecutedonlywhencertainconditionsaremet,andcontroltransferstatementsprovideawaytoaltertheorderinwhichcodeisexecuted.Inaddition,Swiftprovidesadostatementtointroducescope,andcatchandhandleerrors,andadeferstatementforrunningcleanupactionsjustbeforethecurrentscopeexits.

Asemicolon(;)canoptionallyappearafteranystatementandisusedtoseparatemultiplestatementsiftheyappearonthesameline.

GRAMMAR OF A STATEMENT

statement → expression ;optstatement → declaration ;optstatement → loop-statement ;optstatement → branch-statement ;optstatement → labeled-statement ;optstatement → control-transfer-statement ;optstatement → defer-statement ;optstatement → do-statement ;optstatement → compiler-control-statementstatements → statement statements opt

LoopStatements

Page 606: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Loopstatementsallowablockofcodetobeexecutedrepeatedly,dependingontheconditionsspecifiedintheloop.Swifthasthreeloopstatements:afor-instatement,awhilestatement,andarepeat-whilestatement.

ControlflowinaloopstatementcanbechangedbyabreakstatementandacontinuestatementandisdiscussedinBreakStatementandContinueStatementbelow.

GRAMMAR OF A LOOP STATEMENT

loop-statement → for-in-statementloop-statement → while-statementloop-statement → repeat-while-statement

For-InStatementAfor-instatementallowsablockofcodetobeexecutedonceforeachiteminacollection(oranytype)thatconformstotheSequenceprotocol.

Afor-instatementhasthefollowingform:

for item in collection {

statements

}

ThemakeIterator()methodiscalledonthecollectionexpressiontoobtainavalueofaniteratortype—thatis,atypethatconformstotheIteratorProtocolprotocol.Theprogrambeginsexecutingaloopbycallingthenext()methodontheiterator.Ifthevaluereturnedisnotnil,itisassignedtotheitempattern,theprogramexecutesthestatements,andthencontinuesexecutionatthebeginningoftheloop.Otherwise,theprogramdoesnotperformassignmentorexecutethestatements,anditisfinishedexecutingthefor-instatement.

GRAMMAR OF A FOR - IN STATEMENT

for-in-statement → for caseopt pattern in expression where-clause opt code-block

Page 607: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

WhileStatementAwhilestatementallowsablockofcodetobeexecutedrepeatedly,aslongasaconditionremainstrue.

Awhilestatementhasthefollowingform:

while condition {

statements

}

Awhilestatementisexecutedasfollows:

1. Theconditionisevaluated.

Iftrue,executioncontinuestostep2.Iffalse,theprogramisfinishedexecutingthewhilestatement.

2. Theprogramexecutesthestatements,andexecutionreturnstostep1.

Becausethevalueoftheconditionisevaluatedbeforethestatementsareexecuted,thestatementsinawhilestatementcanbeexecutedzeroormoretimes.

ThevalueoftheconditionmustbeoftypeBooloratypebridgedtoBool.Theconditioncanalsobeanoptionalbindingdeclaration,asdiscussedinOptionalBinding.

GRAMMAR OF AWH I LE STATEMENT

while-statement → while condition-list code-blockcondition-list → condition | condition , condition-listcondition → expression | availability-condition | case-condition | optional-binding-

conditioncase-condition → case pattern initializeroptional-binding-condition → let pattern initializer | var pattern initializer

Repeat-WhileStatement

Page 608: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Arepeat-whilestatementallowsablockofcodetobeexecutedoneormoretimes,aslongasaconditionremainstrue.

Arepeat-whilestatementhasthefollowingform:

repeat{

statements

}while condition

Arepeat-whilestatementisexecutedasfollows:

1. Theprogramexecutesthestatements,andexecutioncontinuestostep2.

2. Theconditionisevaluated.

Iftrue,executionreturnstostep1.Iffalse,theprogramisfinishedexecutingtherepeat-whilestatement.

Becausethevalueoftheconditionisevaluatedafterthestatementsareexecuted,thestatementsinarepeat-whilestatementareexecutedatleastonce.

ThevalueoftheconditionmustbeoftypeBooloratypebridgedtoBool.Theconditioncanalsobeanoptionalbindingdeclaration,asdiscussedinOptionalBinding.

GRAMMAR OF AREPEAT-WH I LE STATEMENT

repeat-while-statement → repeat code-block while expression

BranchStatements

Branchstatementsallowtheprogramtoexecutecertainpartsofcodedependingonthevalueofoneormoreconditions.Thevaluesoftheconditionsspecifiedinabranchstatementcontrolhowtheprogrambranchesand,therefore,whatblockofcodeisexecuted.Swifthasthreebranchstatements:anifstatement,aguardstatement,andaswitchstatement.

Page 609: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ControlflowinanifstatementoraswitchstatementcanbechangedbyabreakstatementandisdiscussedinBreakStatementbelow.

GRAMMAR OF A BRANCH STATEMENT

branch-statement → if-statementbranch-statement → guard-statementbranch-statement → switch-statement

IfStatementAnifstatementisusedforexecutingcodebasedontheevaluationofoneormoreconditions.

Therearetwobasicformsofanifstatement.Ineachform,theopeningandclosingbracesarerequired.

Thefirstformallowscodetobeexecutedonlywhenaconditionistrueandhasthefollowingform:

if condition {

statements

}

Thesecondformofanifstatementprovidesanadditionalelseclause(introducedbytheelsekeyword)andisusedforexecutingonepartofcodewhentheconditionistrueandanotherpartofcodewhenthesameconditionisfalse.Whenasingleelseclauseispresent,anifstatementhasthefollowingform:

if condition {

statementstoexecuteifconditionistrue

}else{

statementstoexecuteifconditionisfalse

}

Theelseclauseofanifstatementcancontainanotherifstatementtotestmore

Page 610: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

thanonecondition.Anifstatementchainedtogetherinthiswayhasthefollowingform:

if condition1 {

statementstoexecuteifcondition1istrue

}elseif condition2 {

statementstoexecuteifcondition2istrue

}else{

statementstoexecuteifbothconditionsarefalse

}

ThevalueofanyconditioninanifstatementmustbeoftypeBooloratypebridgedtoBool.Theconditioncanalsobeanoptionalbindingdeclaration,asdiscussedinOptionalBinding.

GRAMMAR OF AN I F STATEMENT

if-statement → if condition-list code-block else-clause optelse-clause → else code-block | else if-statement

GuardStatementAguardstatementisusedtotransferprogramcontroloutofascopeifoneormoreconditionsaren’tmet.

Aguardstatementhasthefollowingform:

guard condition else{

statements

}

ThevalueofanyconditioninaguardstatementmustbeoftypeBooloratypebridgedtoBool.Theconditioncanalsobeanoptionalbindingdeclaration,asdiscussedinOptionalBinding.

Anyconstantsorvariablesassignedavaluefromanoptionalbindingdeclaration

Page 611: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

inaguardstatementconditioncanbeusedfortherestoftheguardstatement’senclosingscope.

Theelseclauseofaguardstatementisrequired,andmusteithercallafunctionwiththeNeverreturntypeortransferprogramcontroloutsidetheguardstatement’senclosingscopeusingoneofthefollowingstatements:

return

break

continue

throw

ControltransferstatementsarediscussedinControlTransferStatementsbelow.FormoreinformationonfunctionswiththeNeverreturntype,seeFunctionsthatNeverReturn.

GRAMMAR OF AGUARD STATEMENT

guard-statement → guard condition-list else code-block

SwitchStatementAswitchstatementallowscertainblocksofcodetobeexecuteddependingonthevalueofacontrolexpression.

Aswitchstatementhasthefollowingform:

switch controlexpression {

case pattern1 :

statements

case pattern2 where condition :

statements

case pattern3 where condition ,

pattern4 where condition :

Page 612: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

statements

default:

statements

}

Thecontrolexpressionoftheswitchstatementisevaluatedandthencomparedwiththepatternsspecifiedineachcase.Ifamatchisfound,theprogramexecutesthestatementslistedwithinthescopeofthatcase.Thescopeofeachcasecan’tbeempty.Asaresult,youmustincludeatleastonestatementfollowingthecolon(:)ofeachcaselabel.Useasinglebreakstatementifyoudon’tintendtoexecuteanycodeinthebodyofamatchedcase.

Thevaluesofexpressionsyourcodecanbranchonareveryflexible.Forexample,inadditiontothevaluesofscalartypes,suchasintegersandcharacters,yourcodecanbranchonthevaluesofanytype,includingfloating-pointnumbers,strings,tuples,instancesofcustomclasses,andoptionals.Thevalueofthecontrolexpressioncanevenbematchedtothevalueofacaseinanenumerationandcheckedforinclusioninaspecifiedrangeofvalues.Forexamplesofhowtousethesevarioustypesofvaluesinswitchstatements,seeSwitchinControlFlow.

Aswitchcasecanoptionallycontainawhereclauseaftereachpattern.Awhereclauseisintroducedbythewherekeywordfollowedbyanexpression,andisusedtoprovideanadditionalconditionbeforeapatterninacaseisconsideredmatchedtothecontrolexpression.Ifawhereclauseispresent,thestatementswithintherelevantcaseareexecutedonlyifthevalueofthecontrolexpressionmatchesoneofthepatternsofthecaseandtheexpressionofthewhereclauseevaluatestotrue.Forexample,acontrolexpressionmatchesthecaseintheexamplebelowonlyifitisatuplethatcontainstwoelementsofthesamevalue,suchas(1,1).

caselet(x,y)wherex==y:

Astheaboveexampleshows,patternsinacasecanalsobindconstantsusingtheletkeyword(theycanalsobindvariablesusingthevarkeyword).Theseconstants(orvariables)canthenbereferencedinacorrespondingwhereclause

Page 613: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

andthroughouttherestofthecodewithinthescopeofthecase.Ifthecasecontainsmultiplepatternsthatmatchthecontrolexpression,allofthepatternsmustcontainthesameconstantorvariablebindings,andeachboundvariableorconstantmusthavethesametypeinallofthecase’spatterns.

Aswitchstatementcanalsoincludeadefaultcase,introducedbythedefaultkeyword.Thecodewithinadefaultcaseisexecutedonlyifnoothercasesmatchthecontrolexpression.Aswitchstatementcanincludeonlyonedefaultcase,whichmustappearattheendoftheswitchstatement.

Althoughtheactualexecutionorderofpattern-matchingoperations,andinparticulartheevaluationorderofpatternsincases,isunspecified,patternmatchinginaswitchstatementbehavesasiftheevaluationisperformedinsourceorder—thatis,theorderinwhichtheyappearinsourcecode.Asaresult,ifmultiplecasescontainpatternsthatevaluatetothesamevalue,andthuscanmatchthevalueofthecontrolexpression,theprogramexecutesonlythecodewithinthefirstmatchingcaseinsourceorder.

SwitchStatementsMustBeExhaustive

InSwift,everypossiblevalueofthecontrolexpression’stypemustmatchthevalueofatleastonepatternofacase.Whenthissimplyisn’tfeasible(forexample,whenthecontrolexpression’stypeisInt),youcanincludeadefaultcasetosatisfytherequirement.

SwitchingOverFutureEnumerationCases

Anonfrozenenumerationisaspecialkindofenumerationthatmaygainnewenumerationcasesinthefuture—evenafteryoucompileandshipanapp.Switchingoveranonfrozenenumerationrequiresextraconsideration.Whenalibrary’sauthorsmarkanenumerationasnonfrozen,theyreservetherighttoaddnewenumerationcases,andanycodethatinteractswiththatenumerationmustbeabletohandlethosefuturecaseswithoutbeingrecompiled.Codethat’scompiledinlibraryevolutionmode,codeinthestandardlibrary,SwiftoverlaysforAppleframeworks,andCandObjective-Ccodecandeclarenonfrozenenumerations.Forinformationaboutfrozenandnonfrozenenumerations,seefrozen.

Page 614: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Whenswitchingoveranonfrozenenumerationvalue,youalwaysneedtoincludeadefaultcase,evenifeverycaseoftheenumerationalreadyhasacorrespondingswitchcase.Youcanapplythe@unknownattributetothedefaultcase,whichindicatesthatthedefaultcaseshouldmatchonlyenumerationcasesthatareaddedinthefuture.Swiftproducesawarningifthedefaultcasematchesanyenumerationcasethatisknownatcompilertime.Thisfuturewarninginformsyouthatthelibraryauthoraddedanewcasetotheenumerationthatdoesn’thaveacorrespondingswitchcase.

Thefollowingexampleswitchesoverallthreeexistingcasesofthestandardlibrary’sMirror.AncestorRepresentationenumeration.Ifyouaddadditionalcasesinthefuture,thecompilergeneratesawarningtoindicatethatyouneedtoupdatetheswitchstatementtotakethenewcasesintoaccount.

1 letrepresentation:Mirror.AncestorRepresentation=.generated

2 switchrepresentation{

3 case.customized:

4 print("Usethenearestancestor’simplementation.")

5 case.generated:

6 print("Generateadefaultmirrorforallancestor

classes.")

7 case.suppressed:

8 print("Suppresstherepresentationofallancestor

classes.")

9 @unknowndefault:

10 print("Usearepresentationthatwasunknownwhenthis

codewascompiled.")

11 }

12 //Prints"Generateadefaultmirrorforallancestor

classes."

ExecutionDoesNotFallThroughCasesImplicitly

Page 615: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Afterthecodewithinamatchedcasehasfinishedexecuting,theprogramexitsfromtheswitchstatement.Programexecutiondoesnotcontinueor“fallthrough”tothenextcaseordefaultcase.Thatsaid,ifyouwantexecutiontocontinuefromonecasetothenext,explicitlyincludeafallthroughstatement,whichsimplyconsistsofthefallthroughkeyword,inthecasefromwhichyouwantexecutiontocontinue.Formoreinformationaboutthefallthroughstatement,seeFallthroughStatementbelow.

GRAMMAR OF A SW ITCH STATEMENT

switch-statement → switch expression { switch-cases opt }switch-cases → switch-case switch-cases optswitch-case → case-label statementsswitch-case → default-label statementsswitch-case → conditional-switch-casecase-label → attributes opt case case-item-list :case-item-list → pattern where-clause opt | pattern where-clause opt , case-item-listdefault-label → attributes opt default :where-clause → where where-expressionwhere-expression → expressionconditional-switch-case → switch-if-directive-clause switch-elseif-directive-clauses opt

switch-else-directive-clause opt endif-directiveswitch-if-directive-clause → if-directive compilation-condition switch-cases optswitch-elseif-directive-clauses → elseif-directive-clause switch-elseif-directive-clauses optswitch-elseif-directive-clause → elseif-directive compilation-condition switch-cases optswitch-else-directive-clause → else-directive switch-cases opt

LabeledStatement

Youcanprefixaloopstatement,anifstatement,aswitchstatement,oradostatementwithastatementlabel,whichconsistsofthenameofthelabelfollowedimmediatelybyacolon(:).Usestatementlabelswithbreakandcontinuestatementstobeexplicitabouthowyouwanttochangecontrolflowinaloopstatementoraswitchstatement,asdiscussedinBreakStatementandContinueStatementbelow.

Thescopeofalabeledstatementistheentirestatementfollowingthestatementlabel.Youcannestlabeledstatements,butthenameofeachstatementlabelmust

Page 616: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

beunique.

Formoreinformationandtoseeexamplesofhowtousestatementlabels,seeLabeledStatementsinControlFlow.

GRAMMAR OF A LABELED STATEMENT

labeled-statement → statement-label loop-statementlabeled-statement → statement-label if-statementlabeled-statement → statement-label switch-statementlabeled-statement → statement-label do-statementstatement-label → label-name :label-name → identifier

ControlTransferStatements

Controltransferstatementscanchangetheorderinwhichcodeinyourprogramisexecutedbyunconditionallytransferringprogramcontrolfromonepieceofcodetoanother.Swifthasfivecontroltransferstatements:abreakstatement,acontinuestatement,afallthroughstatement,areturnstatement,andathrowstatement.

GRAMMAR OF ACONTROLTRANSFER STATEMENT

control-transfer-statement → break-statementcontrol-transfer-statement → continue-statementcontrol-transfer-statement → fallthrough-statementcontrol-transfer-statement → return-statementcontrol-transfer-statement → throw-statement

BreakStatementAbreakstatementendsprogramexecutionofaloop,anifstatement,oraswitchstatement.Abreakstatementcanconsistofonlythebreakkeyword,oritcanconsistofthebreakkeywordfollowedbythenameofastatementlabel,asshownbelow.

break

Page 617: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

break labelname

Whenabreakstatementisfollowedbythenameofastatementlabel,itendsprogramexecutionoftheloop,ifstatement,orswitchstatementnamedbythatlabel.

Whenabreakstatementisnotfollowedbythenameofastatementlabel,itendsprogramexecutionoftheswitchstatementortheinnermostenclosingloopstatementinwhichitoccurs.Youcan’tuseanunlabeledbreakstatementtobreakoutofanifstatement.

Inbothcases,programcontrolisthentransferredtothefirstlineofcodefollowingtheenclosinglooporswitchstatement,ifany.

Forexamplesofhowtouseabreakstatement,seeBreakandLabeledStatementsinControlFlow.

GRAMMAR OF A BREAK STATEMENT

break-statement → break label-name opt

ContinueStatementAcontinuestatementendsprogramexecutionofthecurrentiterationofaloopstatementbutdoesnotstopexecutionoftheloopstatement.Acontinuestatementcanconsistofonlythecontinuekeyword,oritcanconsistofthecontinuekeywordfollowedbythenameofastatementlabel,asshownbelow.

continue

continue labelname

Whenacontinuestatementisfollowedbythenameofastatementlabel,itendsprogramexecutionofthecurrentiterationoftheloopstatementnamedbythatlabel.

Whenacontinuestatementisnotfollowedbythenameofastatementlabel,itendsprogramexecutionofthecurrentiterationoftheinnermostenclosingloop

Page 618: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

statementinwhichitoccurs.

Inbothcases,programcontrolisthentransferredtotheconditionoftheenclosingloopstatement.

Inaforstatement,theincrementexpressionisstillevaluatedafterthecontinuestatementisexecuted,becausetheincrementexpressionisevaluatedaftertheexecutionoftheloop’sbody.

Forexamplesofhowtouseacontinuestatement,seeContinueandLabeledStatementsinControlFlow.

GRAMMAR OF ACONT INUE STATEMENT

continue-statement → continue label-name opt

FallthroughStatementAfallthroughstatementconsistsofthefallthroughkeywordandoccursonlyinacaseblockofaswitchstatement.Afallthroughstatementcausesprogramexecutiontocontinuefromonecaseinaswitchstatementtothenextcase.Programexecutioncontinuestothenextcaseevenifthepatternsofthecaselabeldonotmatchthevalueoftheswitchstatement’scontrolexpression.

Afallthroughstatementcanappearanywhereinsideaswitchstatement,notjustasthelaststatementofacaseblock,butitcan’tbeusedinthefinalcaseblock.Italsocannottransfercontrolintoacaseblockwhosepatterncontainsvaluebindingpatterns.

Foranexampleofhowtouseafallthroughstatementinaswitchstatement,seeControlTransferStatementsinControlFlow.

GRAMMAR OF A FALLTHROUGH STATEMENT

fallthrough-statement → fallthrough

ReturnStatement

Page 619: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Areturnstatementoccursinthebodyofafunctionormethoddefinitionandcausesprogramexecutiontoreturntothecallingfunctionormethod.Programexecutioncontinuesatthepointimmediatelyfollowingthefunctionormethodcall.

Areturnstatementcanconsistofonlythereturnkeyword,oritcanconsistofthereturnkeywordfollowedbyanexpression,asshownbelow.

return

return expression

Whenareturnstatementisfollowedbyanexpression,thevalueoftheexpressionisreturnedtothecallingfunctionormethod.Ifthevalueoftheexpressiondoesnotmatchthevalueofthereturntypedeclaredinthefunctionormethoddeclaration,theexpression’svalueisconvertedtothereturntypebeforeitisreturnedtothecallingfunctionormethod.

NOTE

AsdescribedinFailableInitializers,aspecialformofthereturnstatement(returnnil)canbeusedinafailableinitializertoindicateinitializationfailure.

Whenareturnstatementisnotfollowedbyanexpression,itcanbeusedonlytoreturnfromafunctionormethodthatdoesnotreturnavalue(thatis,whenthereturntypeofthefunctionormethodisVoidor()).

GRAMMAR OF ARETURN STATEMENT

return-statement → return expression opt

ThrowStatementAthrowstatementoccursinthebodyofathrowingfunctionormethod,orinthebodyofaclosureexpressionwhosetypeismarkedwiththethrowskeyword.

Athrowstatementcausesaprogramtoendexecutionofthecurrentscopeandbeginerrorpropagationtoitsenclosingscope.Theerrorthat’sthrowncontinues

Page 620: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

topropagateuntilit’shandledbyacatchclauseofadostatement.

Athrowstatementconsistsofthethrowkeywordfollowedbyanexpression,asshownbelow.

throw expression

ThevalueoftheexpressionmusthaveatypethatconformstotheErrorprotocol.

Foranexampleofhowtouseathrowstatement,seePropagatingErrorsUsingThrowingFunctionsinErrorHandling.

GRAMMAR OF ATHROWSTATEMENT

throw-statement → throw expression

DeferStatement

Adeferstatementisusedforexecutingcodejustbeforetransferringprogramcontroloutsideofthescopethatthedeferstatementappearsin.

Adeferstatementhasthefollowingform:

defer{

statements

}

Thestatementswithinthedeferstatementareexecutednomatterhowprogramcontrolistransferred.Thismeansthatadeferstatementcanbeused,forexample,toperformmanualresourcemanagementsuchasclosingfiledescriptors,andtoperformactionsthatneedtohappenevenifanerroristhrown.

Ifmultipledeferstatementsappearinthesamescope,theordertheyappearisthereverseoftheordertheyareexecuted.Executingthelastdeferstatementina

Page 621: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

givenscopefirstmeansthatstatementsinsidethatlastdeferstatementcanrefertoresourcesthatwillbecleanedupbyotherdeferstatements.

1 funcf(){

2 defer{print("Firstdefer")}

3 defer{print("Seconddefer")}

4 print("Endoffunction")

5 }

6 f()

7 //Prints"Endoffunction"

8 //Prints"Seconddefer"

9 //Prints"Firstdefer"

Thestatementsinthedeferstatementcan’ttransferprogramcontroloutsideofthedeferstatement.

GRAMMAR OF ADEFER STATEMENT

defer-statement → defer code-block

DoStatement

Thedostatementisusedtointroduceanewscopeandcanoptionallycontainoneormorecatchclauses,whichcontainpatternsthatmatchagainstdefinederrorconditions.Variablesandconstantsdeclaredinthescopeofadostatementcanbeaccessedonlywithinthatscope.

AdostatementinSwiftissimilartocurlybraces({})inCusedtodelimitacodeblock,anddoesnotincuraperformancecostatruntime.

Adostatementhasthefollowingform:

do{

Page 622: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

try expression

statements

}catch pattern1 {

statements

}catch pattern2 where condition {

statements

}

Likeaswitchstatement,thecompilerattemptstoinferwhethercatchclausesareexhaustive.Ifsuchadeterminationcanbemade,theerrorisconsideredhandled.Otherwise,theerrorcanpropagateoutofthecontainingscope,whichmeanstheerrormustbehandledbyanenclosingcatchclauseorthecontainingfunctionmustbedeclaredwiththrows.

Toensurethatanerrorishandled,useacatchclausewithapatternthatmatchesallerrors,suchasawildcardpattern(_).Ifacatchclausedoesnotspecifyapattern,thecatchclausematchesandbindsanyerrortoalocalconstantnamederror.Formoreinformationaboutthepatternsyoucanuseinacatchclause,seePatterns.

Toseeanexampleofhowtouseadostatementwithseveralcatchclauses,seeHandlingErrors.

GRAMMAR OF ADO STATEMENT

do-statement → do code-block catch-clauses optcatch-clauses → catch-clause catch-clauses optcatch-clause → catch pattern opt where-clause opt code-block

CompilerControlStatements

Compilercontrolstatementsallowtheprogramtochangeaspectsofthecompiler’sbehavior.Swifthasthreecompilercontrolstatements:aconditionalcompilationblockalinecontrolstatement,andacompile-timediagnosticstatement.

Page 623: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF ACOMP I LER CONTROLSTATEMENT

compiler-control-statement → conditional-compilation-blockcompiler-control-statement → line-control-statementcompiler-control-statement → diagnostic-statement

ConditionalCompilationBlockAconditionalcompilationblockallowscodetobeconditionallycompileddependingonthevalueofoneormorecompilationconditions.

Everyconditionalcompilationblockbeginswiththe#ifcompilationdirectiveandendswiththe#endifcompilationdirective.Asimpleconditionalcompilationblockhasthefollowingform:

#if compilationcondition

statements

#endif

Unliketheconditionofanifstatement,thecompilationconditionisevaluatedatcompiletime.Asaresult,thestatementsarecompiledandexecutedonlyifthecompilationconditionevaluatestotrueatcompiletime.

ThecompilationconditioncanincludethetrueandfalseBooleanliterals,anidentifierusedwiththe-Dcommandlineflag,oranyoftheplatformconditionslistedinthetablebelow.

Platformcondition Validarguments

os() macOS,iOS,watchOS,tvOS,Linux

arch() i386,x86_64,arm,arm64

swift() >=or<followedbyaversionnumber

Page 624: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

compiler() >=or<followedbyaversionnumber

canImport() Amodulename

targetEnvironment() simulator,macCatalyst

Theversionnumberfortheswift()andcompiler()platformconditionsconsistsofamajornumber,optionalminornumber,optionalpatchnumber,andsoon,withadot(.)separatingeachpartoftheversionnumber.Theremustnotbewhitespacebetweenthecomparisonoperatorandtheversionnumber.Theversionforcompiler()isthecompilerversion,regardlessoftheSwiftversionsettingpassedtothecompiler.Theversionforswift()isthelanguageversioncurrentlybeingcompiled.Forexample,ifyoucompileyourcodeusingtheSwift5compilerinSwift4.2mode,thecompilerversionis5andthelanguageversionis4.2.Withthosesettings,thefollowingcodeprintsallthreemessages:

1 #ifcompiler(>=5)

2 print("CompiledwiththeSwift5compilerorlater")

3 #endif

4 #ifswift(>=4.2)

5 print("CompiledinSwift4.2modeorlater")

6 #endif

7 #ifcompiler(>=5)&&swift(<5)

8 print("CompiledwiththeSwift5compilerorlaterinaSwift

modeearlierthan5")

9 #endif

10 //Prints"CompiledwiththeSwift5compilerorlater"

11 //Prints"CompiledinSwift4.2modeorlater"

12 //Prints"CompiledwiththeSwift5compilerorlaterina

Swiftmodeearlierthan5"

Page 625: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheargumentforthecanImport()platformconditionisthenameofamodulethatmaynotbepresentonallplatforms.Thisconditiontestswhetherit’spossibletoimportthemodule,butdoesn’tactuallyimportit.Ifthemoduleispresent,theplatformconditionreturnstrue;otherwise,itreturnsfalse.

ThetargetEnvironment()platformconditionreturnstruewhencodeiscompiledforasimulator;otherwise,itreturnsfalse.

NOTE

Thearch(arm)platformconditiondoesnotreturntrueforARM64devices.Thearch(i386)platformconditionreturnstruewhencodeiscompiledforthe32–bitiOSsimulator.

Youcancombinecompilationconditionsusingthelogicaloperators&&,||,and!anduseparenthesesforgrouping.TheseoperatorshavethesameassociativityandprecedenceasthelogicaloperatorsthatareusedtocombineordinaryBooleanexpressions.

Similartoanifstatement,youcanaddmultipleconditionalbranchestotestfordifferentcompilationconditions.Youcanaddanynumberofadditionalbranchesusing#elseifclauses.Youcanalsoaddafinaladditionalbranchusingan#elseclause.Conditionalcompilationblocksthatcontainmultiplebrancheshavethefollowingform:

#if compilationcondition1

statementstocompileifcompilationcondition1istrue

#elseif compilationcondition2

statementstocompileifcompilationcondition2istrue

#else

statementstocompileifbothcompilationconditionsarefalse

#endif

NOTE

Eachstatementinthebodyofaconditionalcompilationblockisparsedevenifit’snotcompiled.However,thereisanexceptionifthecompilationconditionincludesaswift()platformcondition:Thestatementsareparsedonlyifthecompiler’sversionofSwiftmatcheswhatisspecifiedinthe

Page 626: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

platformcondition.Thisexceptionensuresthatanoldercompilerdoesn’tattempttoparsesyntaxintroducedinanewerversionofSwift.

GRAMMAR OF ACOND I T IONALCOMP I LAT ION BLOCK

conditional-compilation-block → if-directive-clause elseif-directive-clauses opt else-directive-clause opt endif-directive

if-directive-clause → if-directive compilation-condition statements optelseif-directive-clauses → elseif-directive-clause elseif-directive-clauses optelseif-directive-clause → elseif-directive compilation-condition statements optelse-directive-clause → else-directive statements optif-directive → #ifelseif-directive → #elseifelse-directive → #elseendif-directive → #endifcompilation-condition → platform-conditioncompilation-condition → identifiercompilation-condition → boolean-literalcompilation-condition → ( compilation-condition )compilation-condition → ! compilation-conditioncompilation-condition → compilation-condition && compilation-conditioncompilation-condition → compilation-condition || compilation-conditionplatform-condition → os ( operating-system )platform-condition → arch ( architecture )platform-condition → swift ( >= swift-version ) | swift ( < swift-version )platform-condition → compiler ( >= swift-version ) | compiler ( < swift-version

)

platform-condition → canImport ( module-name )platform-condition → targetEnvironment ( environment )operating-system → macOS | iOS | watchOS | tvOSarchitecture → i386 | x86_64 | arm | arm64swift-version → decimal-digits swift-version-continuation optswift-version-continuation → . decimal-digits swift-version-continuation optmodule-name → identifierenvironment → simulator

LineControlStatementAlinecontrolstatementisusedtospecifyalinenumberandfilenamethatcanbedifferentfromthelinenumberandfilenameofthesourcecodebeingcompiled.UsealinecontrolstatementtochangethesourcecodelocationusedbySwiftfordiagnosticanddebuggingpurposes.

Page 627: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Alinecontrolstatementhasthefollowingforms:

#sourceLocation(file: filename ,line: linenumber )

#sourceLocation()

Thefirstformofalinecontrolstatementchangesthevaluesofthe#lineand#fileliteralexpressions,beginningwiththelineofcodefollowingthelinecontrolstatement.Thelinenumberchangesthevalueof#lineandisanyintegerliteralgreaterthanzero.Thefilenamechangesthevalueof#fileandisastringliteral.

Thesecondformofalinecontrolstatement,#sourceLocation(),resetsthesourcecodelocationbacktothedefaultlinenumberingandfilename.

GRAMMAR OF A L I NE CONTROLSTATEMENT

line-control-statement → #sourceLocation ( file: file-name , line: line-number )

line-control-statement → #sourceLocation ( )line-number → Adecimalintegergreaterthanzerofile-name → static-string-literal

Compile-TimeDiagnosticStatementAcompile-timediagnosticstatementcausesthecompilertoemitanerrororawarningduringcompilation.Acompile-timediagnosticstatementhasthefollowingforms:

#error(" errormessage ")

#warning(" warningmessage ")

Thefirstformemitstheerrormessageasafatalerrorandterminatesthecompilationprocess.Thesecondformemitsthewarningmessageasanonfatalwarningandallowscompilationtoproceed.Youwritethediagnosticmessageasastaticstringliteral.Staticstringliteralscan’tusefeatureslikestringinterpolationorconcatenation,buttheycanusethemultilinestringliteralsyntax.

Page 628: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF ACOMP I LE - T IME D I AGNOST IC STATEMENT

diagnostic-statement → #error ( diagnostic-message )diagnostic-statement → #warning ( diagnostic-message )diagnostic-message → static-string-literal

AvailabilityCondition

Anavailabilityconditionisusedasaconditionofanif,while,andguardstatementtoquerytheavailabilityofAPIsatruntime,basedonspecifiedplatformsarguments.

Anavailabilityconditionhasthefollowingform:

if#available( platformname version , ... ,*){

statementstoexecuteiftheAPIsareavailable

}else{

fallbackstatementstoexecuteiftheAPIsareunavailable

}

Youuseanavailabilityconditiontoexecuteablockofcode,dependingonwhethertheAPIsyouwanttouseareavailableatruntime.ThecompilerusestheinformationfromtheavailabilityconditionwhenitverifiesthattheAPIsinthatblockofcodeareavailable.

Theavailabilityconditiontakesacomma-separatedlistofplatformnamesandversions.UseiOS,macOS,watchOS,andtvOSfortheplatformnames,andincludethecorrespondingversionnumbers.The*argumentisrequiredandspecifiesthatonanyotherplatform,thebodyofthecodeblockguardedbytheavailabilityconditionexecutesontheminimumdeploymenttargetspecifiedbyyourtarget.

UnlikeBooleanconditions,youcan’tcombineavailabilityconditionsusing

Page 629: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

logicaloperatorssuchas&&and||.

GRAMMAR OF AN AVA I LAB I L I TY COND I T ION

availability-condition → #available ( availability-arguments )availability-arguments → availability-argument | availability-argument , availability-

argumentsavailability-argument → platform-name platform-versionavailability-argument → *platform-name → iOS | iOSApplicationExtensionplatform-name → macOS | macOSApplicationExtensionplatform-name → watchOSplatform-name → tvOSplatform-version → decimal-digitsplatform-version → decimal-digits . decimal-digitsplatform-version → decimal-digits . decimal-digits . decimal-digits

Page 630: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Declarations

Adeclarationintroducesanewnameorconstructintoyourprogram.Forexample,youusedeclarationstointroducefunctionsandmethods,tointroducevariablesandconstants,andtodefineenumeration,structure,class,andprotocoltypes.Youcanalsouseadeclarationtoextendthebehaviorofanexistingnamedtypeandtoimportsymbolsintoyourprogramthataredeclaredelsewhere.

InSwift,mostdeclarationsarealsodefinitionsinthesensethattheyareimplementedorinitializedatthesametimetheyaredeclared.Thatsaid,becauseprotocolsdon’timplementtheirmembers,mostprotocolmembersaredeclarationsonly.Forconvenienceandbecausethedistinctionisn’tthatimportantinSwift,thetermdeclarationcoversbothdeclarationsanddefinitions.

GRAMMAR OF ADECLARAT ION

declaration → import-declarationdeclaration → constant-declarationdeclaration → variable-declarationdeclaration → typealias-declarationdeclaration → function-declarationdeclaration → enum-declarationdeclaration → struct-declarationdeclaration → class-declarationdeclaration → protocol-declarationdeclaration → initializer-declarationdeclaration → deinitializer-declarationdeclaration → extension-declarationdeclaration → subscript-declarationdeclaration → operator-declarationdeclaration → precedence-group-declarationdeclarations → declaration declarations opt

Top-LevelCode

Thetop-levelcodeinaSwiftsourcefileconsistsofzeroormorestatements,declarations,andexpressions.Bydefault,variables,constants,andothernameddeclarationsthataredeclaredatthetop-levelofasourcefileareaccessibleto

Page 631: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

codeineverysourcefilethatispartofthesamemodule.Youcanoverridethisdefaultbehaviorbymarkingthedeclarationwithanaccess-levelmodifier,asdescribedinAccessControlLevels.

GRAMMAR OF ATOP - LEVELDECLARAT ION

top-level-declaration → statements opt

CodeBlocks

Acodeblockisusedbyavarietyofdeclarationsandcontrolstructurestogroupstatementstogether.Ithasthefollowingform:

{

statements

}

Thestatementsinsideacodeblockincludedeclarations,expressions,andotherkindsofstatementsandareexecutedinorderoftheirappearanceinsourcecode.

GRAMMAR OF ACODE BLOCK

code-block → { statements opt }

ImportDeclaration

Animportdeclarationletsyouaccesssymbolsthataredeclaredoutsidethecurrentfile.Thebasicformimportstheentiremodule;itconsistsoftheimportkeywordfollowedbyamodulename:

import module

Providingmoredetaillimitswhichsymbolsareimported—youcanspecifya

Page 632: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

specificsubmoduleoraspecificdeclarationwithinamoduleorsubmodule.Whenthisdetailedformisused,onlytheimportedsymbol(andnotthemodulethatdeclaresit)ismadeavailableinthecurrentscope.

import importkind module . symbolname

import module . submodule

GRAMMAR OF AN IMPORT DECLARAT ION

import-declaration → attributes opt import import-kind opt import-pathimport-kind → typealias | struct | class | enum | protocol | let | var |

func

import-path → import-path-identifier | import-path-identifier . import-pathimport-path-identifier → identifier | operator

ConstantDeclaration

Aconstantdeclarationintroducesaconstantnamedvalueintoyourprogram.Constantdeclarationsaredeclaredusingtheletkeywordandhavethefollowingform:

let constantname : type = expression

Aconstantdeclarationdefinesanimmutablebindingbetweentheconstantnameandthevalueoftheinitializerexpression;afterthevalueofaconstantisset,itcannotbechanged.Thatsaid,ifaconstantisinitializedwithaclassobject,theobjectitselfcanchange,butthebindingbetweentheconstantnameandtheobjectitreferstocan’t.

Whenaconstantisdeclaredatglobalscope,itmustbeinitializedwithavalue.Whenaconstantdeclarationoccursinthecontextofafunctionormethod,itcanbeinitializedlater,aslongasitisguaranteedtohaveavaluesetbeforethefirsttimeitsvalueisread.Whenaconstantdeclarationoccursinthecontextofaclassorstructuredeclaration,itisconsideredaconstantproperty.Constantdeclarationsarenotcomputedpropertiesandthereforedonothavegettersorsetters.

Page 633: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Iftheconstantnameofaconstantdeclarationisatuplepattern,thenameofeachiteminthetupleisboundtothecorrespondingvalueintheinitializerexpression.

let(firstNumber,secondNumber)=(10,42)

Inthisexample,firstNumberisanamedconstantforthevalue10,andsecondNumberisanamedconstantforthevalue42.Bothconstantscannowbeusedindependently:

1 print("Thefirstnumberis\(firstNumber).")

2 //Prints"Thefirstnumberis10."

3 print("Thesecondnumberis\(secondNumber).")

4 //Prints"Thesecondnumberis42."

Thetypeannotation(:type)isoptionalinaconstantdeclarationwhenthetypeoftheconstantnamecanbeinferred,asdescribedinTypeInference.

Todeclareaconstanttypeproperty,markthedeclarationwiththestaticdeclarationmodifier.Aconstanttypepropertyofaclassisalwaysimplicitlyfinal;youcan’tmarkitwiththeclassorfinaldeclarationmodifiertoallowordisallowoverridingbysubclasses.TypepropertiesarediscussedinTypeProperties.

Formoreinformationaboutconstantsandforguidanceaboutwhentousethem,seeConstantsandVariablesandStoredProperties.

GRAMMAR OF ACONSTANT DECLARAT ION

constant-declaration → attributes opt declaration-modifiers opt let pattern-initializer-list

pattern-initializer-list → pattern-initializer | pattern-initializer , pattern-initializer-listpattern-initializer → pattern initializer optinitializer → = expression

VariableDeclaration

Page 634: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Avariabledeclarationintroducesavariablenamedvalueintoyourprogramandisdeclaredusingthevarkeyword.

Variabledeclarationshaveseveralformsthatdeclaredifferentkindsofnamed,mutablevalues,includingstoredandcomputedvariablesandproperties,storedvariableandpropertyobservers,andstaticvariableproperties.Theappropriateformtousedependsonthescopeatwhichthevariableisdeclaredandthekindofvariableyouintendtodeclare.

NOTE

Youcanalsodeclarepropertiesinthecontextofaprotocoldeclaration,asdescribedinProtocolPropertyDeclaration.

Youcanoverrideapropertyinasubclassbymarkingthesubclass’spropertydeclarationwiththeoverridedeclarationmodifier,asdescribedinOverriding.

StoredVariablesandStoredVariablePropertiesThefollowingformdeclaresastoredvariableorstoredvariableproperty:

var variablename : type = expression

Youdefinethisformofavariabledeclarationatglobalscope,thelocalscopeofafunction,orinthecontextofaclassorstructuredeclaration.Whenavariabledeclarationofthisformisdeclaredatglobalscopeorthelocalscopeofafunction,itisreferredtoasastoredvariable.Whenitisdeclaredinthecontextofaclassorstructuredeclaration,itisreferredtoasastoredvariableproperty.

Theinitializerexpressioncan’tbepresentinaprotocoldeclaration,butinallothercontexts,theinitializerexpressionisoptional.Thatsaid,ifnoinitializerexpressionispresent,thevariabledeclarationmustincludeanexplicittypeannotation(:type).

Aswithconstantdeclarations,ifthevariablenameisatuplepattern,thenameofeachiteminthetupleisboundtothecorrespondingvalueintheinitializerexpression.

Page 635: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Astheirnamessuggest,thevalueofastoredvariableorastoredvariablepropertyisstoredinmemory.

ComputedVariablesandComputedPropertiesThefollowingformdeclaresacomputedvariableorcomputedproperty:

var variablename : type {

get{

statements

}

set( settername ){

statements

}

}

Youdefinethisformofavariabledeclarationatglobalscope,thelocalscopeofafunction,orinthecontextofaclass,structure,enumeration,orextensiondeclaration.Whenavariabledeclarationofthisformisdeclaredatglobalscopeorthelocalscopeofafunction,itisreferredtoasacomputedvariable.Whenitisdeclaredinthecontextofaclass,structure,orextensiondeclaration,itisreferredtoasacomputedproperty.

Thegetterisusedtoreadthevalue,andthesetterisusedtowritethevalue.Thesetterclauseisoptional,andwhenonlyagetterisneeded,youcanomitbothclausesandsimplyreturntherequestedvaluedirectly,asdescribedinRead-OnlyComputedProperties.Butifyouprovideasetterclause,youmustalsoprovideagetterclause.

Thesetternameandenclosingparenthesesisoptional.Ifyouprovideasettername,itisusedasthenameoftheparametertothesetter.Ifyoudonotprovideasettername,thedefaultparameternametothesetterisnewValue,asdescribedinShorthandSetterDeclaration.

Unlikestorednamedvaluesandstoredvariableproperties,thevalueofa

Page 636: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

computednamedvalueoracomputedpropertyisnotstoredinmemory.

Formoreinformationandtoseeexamplesofcomputedproperties,seeComputedProperties.

StoredVariableObserversandPropertyObserversYoucanalsodeclareastoredvariableorpropertywithwillSetanddidSetobservers.Astoredvariableorpropertydeclaredwithobservershasthefollowingform:

var variablename : type = expression {

willSet( settername ){

statements

}

didSet( settername ){

statements

}

}

Youdefinethisformofavariabledeclarationatglobalscope,thelocalscopeofafunction,orinthecontextofaclassorstructuredeclaration.Whenavariabledeclarationofthisformisdeclaredatglobalscopeorthelocalscopeofafunction,theobserversarereferredtoasstoredvariableobservers.Whenitisdeclaredinthecontextofaclassorstructuredeclaration,theobserversarereferredtoaspropertyobservers.

Youcanaddpropertyobserverstoanystoredproperty.Youcanalsoaddpropertyobserverstoanyinheritedproperty(whetherstoredorcomputed)byoverridingthepropertywithinasubclass,asdescribedinOverridingPropertyObservers.

Theinitializerexpressionisoptionalinthecontextofaclassorstructuredeclaration,butrequiredelsewhere.Thetypeannotationisoptionalwhenthetypecanbeinferredfromtheinitializerexpression.

Page 637: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ThewillSetanddidSetobserversprovideawaytoobserve(andtorespondappropriately)whenthevalueofavariableorpropertyisbeingset.Theobserversarenotcalledwhenthevariableorpropertyisfirstinitialized.Instead,theyarecalledonlywhenthevalueissetoutsideofaninitializationcontext.

AwillSetobserveriscalledjustbeforethevalueofthevariableorpropertyisset.ThenewvalueispassedtothewillSetobserverasaconstant,andthereforeitcan’tbechangedintheimplementationofthewillSetclause.ThedidSetobserveriscalledimmediatelyafterthenewvalueisset.IncontrasttothewillSetobserver,theoldvalueofthevariableorpropertyispassedtothedidSetobserverincaseyoustillneedaccesstoit.Thatsaid,ifyouassignavaluetoavariableorpropertywithinitsowndidSetobserverclause,thatnewvaluethatyouassignwillreplacetheonethatwasjustsetandpassedtothewillSetobserver.

ThesetternameandenclosingparenthesesinthewillSetanddidSetclausesareoptional.Ifyouprovidesetternames,theyareusedastheparameternamestothewillSetanddidSetobservers.Ifyoudonotprovidesetternames,thedefaultparameternametothewillSetobserverisnewValueandthedefaultparameternametothedidSetobserverisoldValue.

ThedidSetclauseisoptionalwhenyouprovideawillSetclause.Likewise,thewillSetclauseisoptionalwhenyouprovideadidSetclause.

Formoreinformationandtoseeanexampleofhowtousepropertyobservers,seePropertyObservers.

TypeVariablePropertiesTodeclareatypevariableproperty,markthedeclarationwiththestaticdeclarationmodifier.Classescanmarktypecomputedpropertieswiththeclassdeclarationmodifierinsteadtoallowsubclassestooverridethesuperclass’simplementation.TypepropertiesarediscussedinTypeProperties.

GRAMMAR OF A VAR IABLE DECLARAT ION

variable-declaration → variable-declaration-head pattern-initializer-listvariable-declaration → variable-declaration-head variable-name type-annotation code-

Page 638: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

blockvariable-declaration → variable-declaration-head variable-name type-annotation getter-

setter-blockvariable-declaration → variable-declaration-head variable-name type-annotation getter-

setter-keyword-blockvariable-declaration → variable-declaration-head variable-name initializer willSet-didSet-

blockvariable-declaration → variable-declaration-head variable-name type-annotation

initializer opt willSet-didSet-blockvariable-declaration-head → attributes opt declaration-modifiers opt varvariable-name → identifiergetter-setter-block → code-blockgetter-setter-block → { getter-clause setter-clause opt }getter-setter-block → { setter-clause getter-clause }getter-clause → attributes opt mutation-modifier opt get code-blocksetter-clause → attributes opt mutation-modifier opt set setter-name opt code-blocksetter-name → ( identifier )getter-setter-keyword-block → { getter-keyword-clause setter-keyword-clause opt }getter-setter-keyword-block → { setter-keyword-clause getter-keyword-clause }getter-keyword-clause → attributes opt mutation-modifier opt getsetter-keyword-clause → attributes opt mutation-modifier opt setwillSet-didSet-block → { willSet-clause didSet-clause opt }willSet-didSet-block → { didSet-clause willSet-clause opt }willSet-clause → attributes opt willSet setter-name opt code-blockdidSet-clause → attributes opt didSet setter-name opt code-block

TypeAliasDeclaration

Atypealiasdeclarationintroducesanamedaliasofanexistingtypeintoyourprogram.Typealiasdeclarationsaredeclaredusingthetypealiaskeywordandhavethefollowingform:

typealias name = existingtype

Afteratypealiasisdeclared,thealiasednamecanbeusedinsteadoftheexistingtypeeverywhereinyourprogram.Theexistingtypecanbeanamedtypeoracompoundtype.Typealiasesdonotcreatenewtypes;theysimplyallowanametorefertoanexistingtype.

Page 639: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Atypealiasdeclarationcanusegenericparameterstogiveanametoanexistinggenerictype.Thetypealiascanprovideconcretetypesforsomeorallofthegenericparametersoftheexistingtype.Forexample:

1 typealiasStringDictionary<Value>=Dictionary<String,Value>

2

3 //Thefollowingdictionarieshavethesametype.

4 vardictionary1:StringDictionary<Int>=[:]

5 vardictionary2:Dictionary<String,Int>=[:]

Whenatypealiasisdeclaredwithgenericparameters,theconstraintsonthoseparametersmustmatchexactlytheconstraintsontheexistingtype’sgenericparameters.Forexample:

typealiasDictionaryOfInts<Key:Hashable>=Dictionary<Key,

Int>

Becausethetypealiasandtheexistingtypecanbeusedinterchangeably,thetypealiascan’tintroduceadditionalgenericconstraints.

Atypealiascanforwardanexistingtype’sgenericparametersbyomittingallgenericparametersfromthedeclaration.Forexample,theDiccionariotypealiasdeclaredherehasthesamegenericparametersandconstraintsasDictionary.

typealiasDiccionario=Dictionary

Insideaprotocoldeclaration,atypealiascangiveashorterandmoreconvenientnametoatypethatisusedfrequently.Forexample:

1 protocolSequence{

2 associatedtypeIterator:IteratorProtocol

3 typealiasElement=Iterator.Element

4 }

5

Page 640: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

6 funcsum<T:Sequence>(_sequence:T)->IntwhereT.Element==

Int{

7 //...

8 }

Withoutthistypealias,thesumfunctionwouldhavetorefertotheassociatedtypeasT.Iterator.ElementinsteadofT.Element.

SeealsoProtocolAssociatedTypeDeclaration.

GRAMMAR OF ATYPE AL I AS DECLARAT ION

typealias-declaration → attributes opt access-level-modifier opt typealias typealias-name generic-parameter-clause opt typealias-assignment

typealias-name → identifiertypealias-assignment → = type

FunctionDeclaration

Afunctiondeclarationintroducesafunctionormethodintoyourprogram.Afunctiondeclaredinthecontextofclass,structure,enumeration,orprotocolisreferredtoasamethod.Functiondeclarationsaredeclaredusingthefunckeywordandhavethefollowingform:

func functionname ( parameters )-> returntype {

statements

}

IfthefunctionhasareturntypeofVoid,thereturntypecanbeomittedasfollows:

func functionname ( parameters ){

statements

}

Page 641: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thetypeofeachparametermustbeincluded—itcan’tbeinferred.Ifyouwriteinoutinfrontofaparameter’stype,theparametercanbemodifiedinsidethescopeofthefunction.In-outparametersarediscussedindetailinIn-OutParameters,below.

Afunctiondeclarationwhosestatementsincludeonlyasingleexpressionisunderstoodtoreturnthevalueofthatexpression.

Functionscanreturnmultiplevaluesusingatupletypeasthereturntypeofthefunction.

Afunctiondefinitioncanappearinsideanotherfunctiondeclaration.Thiskindoffunctionisknownasanestedfunction.

Anestedfunctionisnonescapingifitcapturesavaluethatisguaranteedtoneverescape—suchasanin-outparameter—orpassedasanonescapingfunctionargument.Otherwise,thenestedfunctionisanescapingfunction.

Foradiscussionofnestedfunctions,seeNestedFunctions.

ParameterNamesFunctionparametersareacomma-separatedlistwhereeachparameterhasoneofseveralforms.Theorderofargumentsinafunctioncallmustmatchtheorderofparametersinthefunction’sdeclaration.Thesimplestentryinaparameterlisthasthefollowingform:

parametername : parametertype

Aparameterhasaname,whichisusedwithinthefunctionbody,aswellasanargumentlabel,whichisusedwhencallingthefunctionormethod.Bydefault,parameternamesarealsousedasargumentlabels.Forexample:

1 funcf(x:Int,y:Int)->Int{returnx+y}

2 f(x:1,y:2)//bothxandyarelabeled

Page 642: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youcanoverridethedefaultbehaviorforargumentlabelswithoneofthefollowingforms:

argumentlabel parametername : parametertype

_ parametername : parametertype

Anamebeforetheparameternamegivestheparameteranexplicitargumentlabel,whichcanbedifferentfromtheparametername.Thecorrespondingargumentmustusethegivenargumentlabelinfunctionormethodcalls.

Anunderscore(_)beforeaparameternamesuppressestheargumentlabel.Thecorrespondingargumentmusthavenolabelinfunctionormethodcalls.

1 funcrepeatGreeting(_greeting:String,countn:Int){/*

Greetntimes*/}

2 repeatGreeting("Hello,world!",count:2)//countislabeled,

greetingisnot

In-OutParametersIn-outparametersarepassedasfollows:

1. Whenthefunctioniscalled,thevalueoftheargumentiscopied.

2. Inthebodyofthefunction,thecopyismodified.

3. Whenthefunctionreturns,thecopy’svalueisassignedtotheoriginalargument.

Thisbehaviorisknownascopy-incopy-outorcallbyvalueresult.Forexample,whenacomputedpropertyorapropertywithobserversispassedasanin-outparameter,itsgetteriscalledaspartofthefunctioncallanditssetteriscalledaspartofthefunctionreturn.

Asanoptimization,whentheargumentisavaluestoredataphysicaladdressinmemory,thesamememorylocationisusedbothinsideandoutsidethefunction

Page 643: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

body.Theoptimizedbehaviorisknownascallbyreference;itsatisfiesalloftherequirementsofthecopy-incopy-outmodelwhileremovingtheoverheadofcopying.Writeyourcodeusingthemodelgivenbycopy-incopy-out,withoutdependingonthecall-by-referenceoptimization,sothatitbehavescorrectlywithorwithouttheoptimization.

Withinafunction,don’taccessavaluethatwaspassedasanin-outargument,eveniftheoriginalvalueisavailableinthecurrentscope.Accessingtheoriginalisasimultaneousaccessofthevalue,whichviolatesSwift’smemoryexclusivityguarantee.Forthesamereason,youcan’tpassthesamevaluetomultiplein-outparameters.

Formoreinformationaboutmemorysafetyandmemoryexclusivity,seeMemorySafety.

Aclosureornestedfunctionthatcapturesanin-outparametermustbenonescaping.Ifyouneedtocaptureanin-outparameterwithoutmutatingitortoobservechangesmadebyothercode,useacapturelisttoexplicitlycapturetheparameterimmutably.

1 funcsomeFunction(a:inoutInt)->()->Int{

2 return{[a]inreturna+1}

3 }

Ifyouneedtocaptureandmutateanin-outparameter,useanexplicitlocalcopy,suchasinmultithreadedcodethatensuresallmutationhasfinishedbeforethefunctionreturns.

1 funcmultithreadedFunction(queue:DispatchQueue,x:inoutInt)

{

2 //Makealocalcopyandmanuallycopyitback.

3 varlocalX=x

4 defer{x=localX}

5

6 //OperateonlocalXasynchronously,thenwaitbefore

Page 644: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

returning.

7 queue.async{someMutatingOperation(&localX)}

8 queue.sync{}

9 }

Formorediscussionandexamplesofin-outparameters,seeIn-OutParameters.

SpecialKindsofParametersParameterscanbeignored,takeavariablenumberofvalues,andprovidedefaultvaluesusingthefollowingforms:

_: parametertype

parametername : parametertype ...

parametername : parametertype = defaultargumentvalue

Anunderscore(_)parameterisexplicitlyignoredandcan’tbeaccessedwithinthebodyofthefunction.

Aparameterwithabasetypenamefollowedimmediatelybythreedots(...)isunderstoodasavariadicparameter.Afunctioncanhaveatmostonevariadicparameter.Avariadicparameteristreatedasanarraythatcontainselementsofthebasetypename.Forexample,thevariadicparameterInt...istreatedas[Int].Foranexamplethatusesavariadicparameter,seeVariadicParameters.

Aparameterwithanequalssign(=)andanexpressionafteritstypeisunderstoodtohaveadefaultvalueofthegivenexpression.Thegivenexpressionisevaluatedwhenthefunctioniscalled.Iftheparameterisomittedwhencallingthefunction,thedefaultvalueisusedinstead.

1 funcf(x:Int=42)->Int{returnx}

2 f()//Valid,usesdefaultvalue

3 f(x:7)//Valid,usesthevalueprovided

4 f(7)//Invalid,missingargumentlabel

Page 645: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

SpecialKindsofMethodsMethodsonanenumerationorastructurethatmodifyselfmustbemarkedwiththemutatingdeclarationmodifier.

Methodsthatoverrideasuperclassmethodmustbemarkedwiththeoverridedeclarationmodifier.It’sacompile-timeerrortooverrideamethodwithouttheoverridemodifierortousetheoverridemodifieronamethodthatdoesn’toverrideasuperclassmethod.

Methodsassociatedwithatyperatherthananinstanceofatypemustbemarkedwiththestaticdeclarationmodifierforenumerationsandstructures,orwitheitherthestaticorclassdeclarationmodifierforclasses.Aclasstypemethodmarkedwiththeclassdeclarationmodifiercanbeoverriddenbyasubclassimplementation;aclasstypemethodmarkedwithclassfinalorstaticcan’tbeoverridden.

ThrowingFunctionsandMethodsFunctionsandmethodsthatcanthrowanerrormustbemarkedwiththethrowskeyword.Thesefunctionsandmethodsareknownasthrowingfunctionsandthrowingmethods.Theyhavethefollowingform:

func functionname ( parameters )throws-> returntype {

statements

}

Callstoathrowingfunctionormethodmustbewrappedinatryortry!expression(thatis,inthescopeofatryortry!operator).

Thethrowskeywordispartofafunction’stype,andnonthrowingfunctionsaresubtypesofthrowingfunctions.Asaresult,youcanuseanonthrowingfunctioninthesameplacesasathrowingone.

Youcan’toverloadafunctionbasedonlyonwhetherthefunctioncanthrowanerror.Thatsaid,youcanoverloadafunctionbasedonwhetherafunctionparametercanthrowanerror.

Page 646: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Athrowingmethodcan’toverrideanonthrowingmethod,andathrowingmethodcan’tsatisfyaprotocolrequirementforanonthrowingmethod.Thatsaid,anonthrowingmethodcanoverrideathrowingmethod,andanonthrowingmethodcansatisfyaprotocolrequirementforathrowingmethod.

RethrowingFunctionsandMethodsAfunctionormethodcanbedeclaredwiththerethrowskeywordtoindicatethatitthrowsanerroronlyifoneofitsfunctionparametersthrowsanerror.Thesefunctionsandmethodsareknownasrethrowingfunctionsandrethrowingmethods.Rethrowingfunctionsandmethodsmusthaveatleastonethrowingfunctionparameter.

1 funcsomeFunction(callback:()throws->Void)rethrows{

2 trycallback()

3 }

Arethrowingfunctionormethodcancontainathrowstatementonlyinsideacatchclause.Thisletsyoucallthethrowingfunctioninsideado-catchblockandhandleerrorsinthecatchclausebythrowingadifferenterror.Inaddition,thecatchclausemusthandleonlyerrorsthrownbyoneoftherethrowingfunction’sthrowingparameters.Forexample,thefollowingisinvalidbecausethecatchclausewouldhandletheerrorthrownbyalwaysThrows().

1 funcalwaysThrows()throws{

2 throwSomeError.error

3 }

4 funcsomeFunction(callback:()throws->Void)rethrows{

5 do{

6 trycallback()

7 tryalwaysThrows()//Invalid,alwaysThrows()isn'ta

throwingparameter

8 }catch{

Page 647: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 throwAnotherError.error

10 }

11 }

Athrowingmethodcan’toverridearethrowingmethod,andathrowingmethodcan’tsatisfyaprotocolrequirementforarethrowingmethod.Thatsaid,arethrowingmethodcanoverrideathrowingmethod,andarethrowingmethodcansatisfyaprotocolrequirementforathrowingmethod.

FunctionsthatNeverReturnSwiftdefinesaNevertype,whichindicatesthatafunctionormethoddoesn’treturntoitscaller.FunctionsandmethodswiththeNeverreturntypearecallednonreturning.Nonreturningfunctionsandmethodseithercauseanirrecoverableerrororbeginasequenceofworkthatcontinuesindefinitely.Thismeansthatcodethatwouldotherwiserunimmediatelyafterthecallisneverexecuted.Throwingandrethrowingfunctionscantransferprogramcontroltoanappropriatecatchblock,evenwhentheyarenonreturning.

Anonreturningfunctionormethodcanbecalledtoconcludetheelseclauseofaguardstatement,asdiscussedinGuardStatement.

Youcanoverrideanonreturningmethod,butthenewmethodmustpreserveitsreturntypeandnonreturningbehavior.

GRAMMAR OF A FUNCT ION DECLARAT ION

function-declaration → function-head function-name generic-parameter-clause optfunction-signature generic-where-clause opt function-body opt

function-head → attributes opt declaration-modifiers opt funcfunction-name → identifier | operatorfunction-signature → parameter-clause throwsopt function-result optfunction-signature → parameter-clause rethrows function-result optfunction-result → -> attributes opt typefunction-body → code-blockparameter-clause → ( ) | ( parameter-list )parameter-list → parameter | parameter , parameter-listparameter → external-parameter-name opt local-parameter-name type-annotation

Page 648: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

default-argument-clause optparameter → external-parameter-name opt local-parameter-name type-annotationparameter → external-parameter-name opt local-parameter-name type-annotation ...external-parameter-name → identifierlocal-parameter-name → identifierdefault-argument-clause → = expression

EnumerationDeclaration

Anenumerationdeclarationintroducesanamedenumerationtypeintoyourprogram.

Enumerationdeclarationshavetwobasicformsandaredeclaredusingtheenumkeyword.Thebodyofanenumerationdeclaredusingeitherformcontainszeroormorevalues—calledenumerationcases—andanynumberofdeclarations,includingcomputedproperties,instancemethods,typemethods,initializers,typealiases,andevenotherenumeration,structure,andclassdeclarations.Enumerationdeclarationscan’tcontaindeinitializerorprotocoldeclarations.

Enumerationtypescanadoptanynumberofprotocols,butcan’tinheritfromclasses,structures,orotherenumerations.

Unlikeclassesandstructures,enumerationtypesdonothaveanimplicitlyprovideddefaultinitializer;allinitializersmustbedeclaredexplicitly.Initializerscandelegatetootherinitializersintheenumeration,buttheinitializationprocessiscompleteonlyafteraninitializerassignsoneoftheenumerationcasestoself.

Likestructuresbutunlikeclasses,enumerationsarevaluetypes;instancesofanenumerationarecopiedwhenassignedtovariablesorconstants,orwhenpassedasargumentstoafunctioncall.Forinformationaboutvaluetypes,seeStructuresandEnumerationsAreValueTypes.

Youcanextendthebehaviorofanenumerationtypewithanextensiondeclaration,asdiscussedinExtensionDeclaration.

Page 649: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

EnumerationswithCasesofAnyTypeThefollowingformdeclaresanenumerationtypethatcontainsenumerationcasesofanytype:

enum enumerationname : adoptedprotocols {

case enumerationcase1

case enumerationcase2 ( associatedvaluetypes )

}

Enumerationsdeclaredinthisformaresometimescalleddiscriminatedunionsinotherprogramminglanguages.

Inthisform,eachcaseblockconsistsofthecasekeywordfollowedbyoneormoreenumerationcases,separatedbycommas.Thenameofeachcasemustbeunique.Eachcasecanalsospecifythatitstoresvaluesofagiventype.Thesetypesarespecifiedintheassociatedvaluetypestuple,immediatelyfollowingthenameofthecase.

Enumerationcasesthatstoreassociatedvaluescanbeusedasfunctionsthatcreateinstancesoftheenumerationwiththespecifiedassociatedvalues.Andjustlikefunctions,youcangetareferencetoanenumerationcaseandapplyitlaterinyourcode.

1 enumNumber{

2 caseinteger(Int)

3 casereal(Double)

4 }

5 letf=Number.integer

6 //fisafunctionoftype(Int)->Number

7

8 //ApplyftocreateanarrayofNumberinstanceswithinteger

values

9 letevenInts:[Number]=[0,2,4,6].map(f)

Page 650: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Formoreinformationandtoseeexamplesofcaseswithassociatedvaluetypes,seeAssociatedValues.

EnumerationswithIndirection

Enumerationscanhavearecursivestructure,thatis,theycanhavecaseswithassociatedvaluesthatareinstancesoftheenumerationtypeitself.However,instancesofenumerationtypeshavevaluesemantics,whichmeanstheyhaveafixedlayoutinmemory.Tosupportrecursion,thecompilermustinsertalayerofindirection.

Toenableindirectionforaparticularenumerationcase,markitwiththeindirectdeclarationmodifier.Anindirectcasemusthaveanassociatedvalue.

1 enumTree<T>{

2 caseempty

3 indirectcasenode(value:T,left:Tree,right:Tree)

4 }

Toenableindirectionforallthecasesofanenumerationthathaveanassociatedvalue,marktheentireenumerationwiththeindirectmodifier—thisisconvenientwhentheenumerationcontainsmanycasesthatwouldeachneedtobemarkedwiththeindirectmodifier.

Anenumerationthatismarkedwiththeindirectmodifiercancontainamixtureofcasesthathaveassociatedvaluesandcasesthosethatdon’t.Thatsaid,itcan’tcontainanycasesthatarealsomarkedwiththeindirectmodifier.

EnumerationswithCasesofaRaw-ValueTypeThefollowingformdeclaresanenumerationtypethatcontainsenumerationcasesofthesamebasictype:

enum enumerationname : raw-valuetype , adoptedprotocols {

case enumerationcase1 = rawvalue1

Page 651: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

case enumerationcase2 = rawvalue2

}

Inthisform,eachcaseblockconsistsofthecasekeyword,followedbyoneormoreenumerationcases,separatedbycommas.Unlikethecasesinthefirstform,eachcasehasanunderlyingvalue,calledarawvalue,ofthesamebasictype.Thetypeofthesevaluesisspecifiedintheraw-valuetypeandmustrepresentaninteger,floating-pointnumber,string,orsinglecharacter.Inparticular,theraw-valuetypemustconformtotheEquatableprotocolandoneofthefollowingprotocols:ExpressibleByIntegerLiteralforintegerliterals,ExpressibleByFloatLiteralforfloating-pointliterals,ExpressibleByStringLiteralforstringliteralsthatcontainanynumberofcharacters,andExpressibleByUnicodeScalarLiteralorExpressibleByExtendedGraphemeClusterLiteralforstringliteralsthatcontainonlyasinglecharacter.Eachcasemusthaveauniquenameandbeassignedauniquerawvalue.

Iftheraw-valuetypeisspecifiedasIntandyoudon’tassignavaluetothecasesexplicitly,theyareimplicitlyassignedthevalues0,1,2,andsoon.EachunassignedcaseoftypeIntisimplicitlyassignedarawvaluethatisautomaticallyincrementedfromtherawvalueofthepreviouscase.

1 enumExampleEnum:Int{

2 casea,b,c=5,d

3 }

Intheaboveexample,therawvalueofExampleEnum.ais0andthevalueofExampleEnum.bis1.AndbecausethevalueofExampleEnum.cisexplicitlysetto5,thevalueofExampleEnum.disautomaticallyincrementedfrom5andistherefore6.

Iftheraw-valuetypeisspecifiedasStringandyoudon’tassignvaluestothecasesexplicitly,eachunassignedcaseisimplicitlyassignedastringwiththesametextasthenameofthatcase.

1 enumGamePlayMode:String{

Page 652: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2 casecooperative,individual,competitive

3 }

Intheaboveexample,therawvalueofGamePlayMode.cooperativeis"cooperative",therawvalueofGamePlayMode.individualis"individual",andtherawvalueofGamePlayMode.competitiveis"competitive".

Enumerationsthathavecasesofaraw-valuetypeimplicitlyconformtotheRawRepresentableprotocol,definedintheSwiftstandardlibrary.Asaresult,theyhavearawValuepropertyandafailableinitializerwiththesignatureinit?(rawValue:RawValue).YoucanusetherawValuepropertytoaccesstherawvalueofanenumerationcase,asinExampleEnum.b.rawValue.Youcanalsousearawvaluetofindacorrespondingcase,ifthereisone,bycallingtheenumeration’sfailableinitializer,asinExampleEnum(rawValue:5),whichreturnsanoptionalcase.Formoreinformationandtoseeexamplesofcaseswithraw-valuetypes,seeRawValues.

AccessingEnumerationCasesToreferencethecaseofanenumerationtype,usedot(.)syntax,asinEnumerationType.enumerationCase.Whentheenumerationtypecanbeinferredfromcontext,youcanomitit(thedotisstillrequired),asdescribedinEnumerationSyntaxandImplicitMemberExpression.

Tocheckthevaluesofenumerationcases,useaswitchstatement,asshowninMatchingEnumerationValueswithaSwitchStatement.Theenumerationtypeispattern-matchedagainsttheenumerationcasepatternsinthecaseblocksoftheswitchstatement,asdescribedinEnumerationCasePattern.

GRAMMAR OF AN ENUMERAT ION DECLARAT ION

enum-declaration → attributes opt access-level-modifier opt union-style-enumenum-declaration → attributes opt access-level-modifier opt raw-value-style-enumunion-style-enum → indirectopt enum enum-name generic-parameter-clause opt

type-inheritance-clause opt generic-where-clause opt { union-style-enum-members

opt }union-style-enum-members → union-style-enum-member union-style-enum-members optunion-style-enum-member → declaration | union-style-enum-case-clause | compiler-

Page 653: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

control-statementunion-style-enum-case-clause → attributes opt indirectopt case union-style-enum-

case-listunion-style-enum-case-list → union-style-enum-case | union-style-enum-case , union-

style-enum-case-listunion-style-enum-case → enum-case-name tuple-type optenum-name → identifierenum-case-name → identifierraw-value-style-enum → enum enum-name generic-parameter-clause opt type-

inheritance-clause generic-where-clause opt { raw-value-style-enum-members }raw-value-style-enum-members → raw-value-style-enum-member raw-value-style-enum-

members optraw-value-style-enum-member → declaration | raw-value-style-enum-case-clause |

compiler-control-statementraw-value-style-enum-case-clause → attributes opt case raw-value-style-enum-case-

listraw-value-style-enum-case-list → raw-value-style-enum-case | raw-value-style-enum-

case , raw-value-style-enum-case-listraw-value-style-enum-case → enum-case-name raw-value-assignment optraw-value-assignment → = raw-value-literalraw-value-literal → numeric-literal | static-string-literal | boolean-literal

StructureDeclaration

Astructuredeclarationintroducesanamedstructuretypeintoyourprogram.Structuredeclarationsaredeclaredusingthestructkeywordandhavethefollowingform:

struct structurename : adoptedprotocols {

declarations

}

Thebodyofastructurecontainszeroormoredeclarations.Thesedeclarationscanincludebothstoredandcomputedproperties,typeproperties,instancemethods,typemethods,initializers,subscripts,typealiases,andevenotherstructure,class,andenumerationdeclarations.Structuredeclarationscan’tcontaindeinitializerorprotocoldeclarations.Foradiscussionandseveralexamplesofstructuresthatincludevariouskindsofdeclarations,seeStructures

Page 654: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

andClasses.

Structuretypescanadoptanynumberofprotocols,butcan’tinheritfromclasses,enumerations,orotherstructures.

Therearethreewaystocreateaninstanceofapreviouslydeclaredstructure:

Calloneoftheinitializersdeclaredwithinthestructure,asdescribedinInitializers.

Ifnoinitializersaredeclared,callthestructure’smemberwiseinitializer,asdescribedinMemberwiseInitializersforStructureTypes.

Ifnoinitializersaredeclared,andallpropertiesofthestructuredeclarationweregiveninitialvalues,callthestructure’sdefaultinitializer,asdescribedinDefaultInitializers.

Theprocessofinitializingastructure’sdeclaredpropertiesisdescribedinInitialization.

Propertiesofastructureinstancecanbeaccessedusingdot(.)syntax,asdescribedinAccessingProperties.

Structuresarevaluetypes;instancesofastructurearecopiedwhenassignedtovariablesorconstants,orwhenpassedasargumentstoafunctioncall.Forinformationaboutvaluetypes,seeStructuresandEnumerationsAreValueTypes.

Youcanextendthebehaviorofastructuretypewithanextensiondeclaration,asdiscussedinExtensionDeclaration.

GRAMMAR OF A STRUCTURE DECLARAT ION

struct-declaration → attributes opt access-level-modifier opt struct struct-namegeneric-parameter-clause opt type-inheritance-clause opt generic-where-clause optstruct-body

struct-name → identifierstruct-body → { struct-members opt }struct-members → struct-member struct-members optstruct-member → declaration | compiler-control-statement

Page 655: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ClassDeclaration

Aclassdeclarationintroducesanamedclasstypeintoyourprogram.Classdeclarationsaredeclaredusingtheclasskeywordandhavethefollowingform:

class classname : superclass , adoptedprotocols {

declarations

}

Thebodyofaclasscontainszeroormoredeclarations.Thesedeclarationscanincludebothstoredandcomputedproperties,instancemethods,typemethods,initializers,asingledeinitializer,subscripts,typealiases,andevenotherclass,structure,andenumerationdeclarations.Classdeclarationscan’tcontainprotocoldeclarations.Foradiscussionandseveralexamplesofclassesthatincludevariouskindsofdeclarations,seeStructuresandClasses.

Aclasstypecaninheritfromonlyoneparentclass,itssuperclass,butcanadoptanynumberofprotocols.Thesuperclassappearsfirstaftertheclassnameandcolon,followedbyanyadoptedprotocols.Genericclassescaninheritfromothergenericandnongenericclasses,butanongenericclasscaninheritonlyfromothernongenericclasses.Whenyouwritethenameofagenericsuperclassclassafterthecolon,youmustincludethefullnameofthatgenericclass,includingitsgenericparameterclause.

AsdiscussedinInitializerDeclaration,classescanhavedesignatedandconvenienceinitializers.Thedesignatedinitializerofaclassmustinitializealloftheclass’sdeclaredpropertiesanditmustdosobeforecallinganyofitssuperclass’sdesignatedinitializers.

Aclasscanoverrideproperties,methods,subscripts,andinitializersofitssuperclass.Overriddenproperties,methods,subscripts,anddesignatedinitializersmustbemarkedwiththeoverridedeclarationmodifier.

Torequirethatsubclassesimplementasuperclass’sinitializer,markthesuperclass’sinitializerwiththerequireddeclarationmodifier.Thesubclass’simplementationofthatinitializermustalsobemarkedwiththerequireddeclarationmodifier.

Page 656: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Althoughpropertiesandmethodsdeclaredinthesuperclassareinheritedbythecurrentclass,designatedinitializersdeclaredinthesuperclassareonlyinheritedwhenthesubclassmeetstheconditionsdescribedinAutomaticInitializerInheritance.Swiftclassesdonotinheritfromauniversalbaseclass.

Therearetwowaystocreateaninstanceofapreviouslydeclaredclass:

Calloneoftheinitializersdeclaredwithintheclass,asdescribedinInitializers.

Ifnoinitializersaredeclared,andallpropertiesoftheclassdeclarationweregiveninitialvalues,calltheclass’sdefaultinitializer,asdescribedinDefaultInitializers.

Accesspropertiesofaclassinstancewithdot(.)syntax,asdescribedinAccessingProperties.

Classesarereferencetypes;instancesofaclassarereferredto,ratherthancopied,whenassignedtovariablesorconstants,orwhenpassedasargumentstoafunctioncall.Forinformationaboutreferencetypes,seeStructuresandEnumerationsAreValueTypes.

Youcanextendthebehaviorofaclasstypewithanextensiondeclaration,asdiscussedinExtensionDeclaration.

GRAMMAR OF ACLASS DECLARAT ION

class-declaration → attributes opt access-level-modifier opt finalopt class class-name generic-parameter-clause opt type-inheritance-clause opt generic-where-clause

opt class-bodyclass-declaration → attributes opt final access-level-modifier opt class class-

name generic-parameter-clause opt type-inheritance-clause opt generic-where-clause

opt class-bodyclass-name → identifierclass-body → { class-members opt }class-members → class-member class-members optclass-member → declaration | compiler-control-statement

Page 657: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ProtocolDeclaration

Aprotocoldeclarationintroducesanamedprotocoltypeintoyourprogram.Protocoldeclarationsaredeclaredatglobalscopeusingtheprotocolkeywordandhavethefollowingform:

protocol protocolname : inheritedprotocols {

protocolmemberdeclarations

}

Thebodyofaprotocolcontainszeroormoreprotocolmemberdeclarations,whichdescribetheconformancerequirementsthatanytypeadoptingtheprotocolmustfulfill.Inparticular,aprotocolcandeclarethatconformingtypesmustimplementcertainproperties,methods,initializers,andsubscripts.Protocolscanalsodeclarespecialkindsoftypealiases,calledassociatedtypes,thatcanspecifyrelationshipsamongthevariousdeclarationsoftheprotocol.Protocoldeclarationscan’tcontainclass,structure,enumeration,orotherprotocoldeclarations.Theprotocolmemberdeclarationsarediscussedindetailbelow.

Protocoltypescaninheritfromanynumberofotherprotocols.Whenaprotocoltypeinheritsfromotherprotocols,thesetofrequirementsfromthoseotherprotocolsareaggregated,andanytypethatinheritsfromthecurrentprotocolmustconformtoallthoserequirements.Foranexampleofhowtouseprotocolinheritance,seeProtocolInheritance.

NOTE

Youcanalsoaggregatetheconformancerequirementsofmultipleprotocolsusingprotocolcompositiontypes,asdescribedinProtocolCompositionTypeandProtocolComposition.

Youcanaddprotocolconformancetoapreviouslydeclaredtypebyadoptingtheprotocolinanextensiondeclarationofthattype.Intheextension,youmustimplementalloftheadoptedprotocol’srequirements.Ifthetypealreadyimplementsalloftherequirements,youcanleavethebodyoftheextensiondeclarationempty.

Bydefault,typesthatconformtoaprotocolmustimplementallproperties,

Page 658: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

methods,andsubscriptsdeclaredintheprotocol.Thatsaid,youcanmarktheseprotocolmemberdeclarationswiththeoptionaldeclarationmodifiertospecifythattheirimplementationbyaconformingtypeisoptional.Theoptionalmodifiercanbeappliedonlytomembersthataremarkedwiththeobjcattribute,andonlytomembersofprotocolsthataremarkedwiththeobjcattribute.Asaresult,onlyclasstypescanadoptandconformtoaprotocolthatcontainsoptionalmemberrequirements.Formoreinformationabouthowtousetheoptionaldeclarationmodifierandforguidanceabouthowtoaccessoptionalprotocolmembers—forexample,whenyou’renotsurewhetheraconformingtypeimplementsthem—seeOptionalProtocolRequirements.

Torestricttheadoptionofaprotocoltoclasstypesonly,includetheAnyObjectprotocolintheinheritedprotocolslistafterthecolon.Forexample,thefollowingprotocolcanbeadoptedonlybyclasstypes:

1 protocolSomeProtocol:AnyObject{

2 /*Protocolmembersgohere*/

3 }

Anyprotocolthatinheritsfromaprotocolthat’smarkedwiththeAnyObjectrequirementcanlikewisebeadoptedonlybyclasstypes.

NOTE

Ifaprotocolismarkedwiththeobjcattribute,theAnyObjectrequirementisimplicitlyappliedtothatprotocol;there’snoneedtomarktheprotocolwiththeAnyObjectrequirementexplicitly.

Protocolsarenamedtypes,andthustheycanappearinallthesameplacesinyourcodeasothernamedtypes,asdiscussedinProtocolsasTypes.However,youcan’tconstructaninstanceofaprotocol,becauseprotocolsdonotactuallyprovidetheimplementationsfortherequirementstheyspecify.

Youcanuseprotocolstodeclarewhichmethodsadelegateofaclassorstructureshouldimplement,asdescribedinDelegation.

GRAMMAR OF A PROTOCOLDECLARAT ION

protocol-declaration → attributes opt access-level-modifier opt protocol protocol-

Page 659: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

name type-inheritance-clause opt generic-where-clause opt protocol-bodyprotocol-name → identifierprotocol-body → { protocol-members opt }protocol-members → protocol-member protocol-members optprotocol-member → protocol-member-declaration | compiler-control-statementprotocol-member-declaration → protocol-property-declarationprotocol-member-declaration → protocol-method-declarationprotocol-member-declaration → protocol-initializer-declarationprotocol-member-declaration → protocol-subscript-declarationprotocol-member-declaration → protocol-associated-type-declarationprotocol-member-declaration → typealias-declaration

ProtocolPropertyDeclarationProtocolsdeclarethatconformingtypesmustimplementapropertybyincludingaprotocolpropertydeclarationinthebodyoftheprotocoldeclaration.Protocolpropertydeclarationshaveaspecialformofavariabledeclaration:

var propertyname : type {getset}

Aswithotherprotocolmemberdeclarations,thesepropertydeclarationsdeclareonlythegetterandsetterrequirementsfortypesthatconformtotheprotocol.Asaresult,youdon’timplementthegetterorsetterdirectlyintheprotocolinwhichitisdeclared.

Thegetterandsetterrequirementscanbesatisfiedbyaconformingtypeinavarietyofways.Ifapropertydeclarationincludesboththegetandsetkeywords,aconformingtypecanimplementitwithastoredvariablepropertyoracomputedpropertythatisbothreadableandwriteable(thatis,onethatimplementsbothagetterandasetter).However,thatpropertydeclarationcan’tbeimplementedasaconstantpropertyoraread-onlycomputedproperty.Ifapropertydeclarationincludesonlythegetkeyword,itcanbeimplementedasanykindofproperty.Forexamplesofconformingtypesthatimplementthepropertyrequirementsofaprotocol,seePropertyRequirements.

Todeclareatypepropertyrequirementinaprotocoldeclaration,markthepropertydeclarationwiththestatickeyword.Structuresandenumerationsthatconformtotheprotocoldeclarethepropertywiththestatickeyword,and

Page 660: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

classesthatconformtotheprotocoldeclarethepropertywitheitherthestaticorclasskeyword.Extensionsthataddprotocolconformancetoastructure,enumeration,orclassusethesamekeywordasthetypetheyextenduses.Extensionsthatprovideadefaultimplementationforatypepropertyrequirementusethestatickeyword.

SeealsoVariableDeclaration.

GRAMMAR OF A PROTOCOLPROPERTY DECLARAT ION

protocol-property-declaration → variable-declaration-head variable-name type-annotationgetter-setter-keyword-block

ProtocolMethodDeclarationProtocolsdeclarethatconformingtypesmustimplementamethodbyincludingaprotocolmethoddeclarationinthebodyoftheprotocoldeclaration.Protocolmethoddeclarationshavethesameformasfunctiondeclarations,withtwoexceptions:Theydon’tincludeafunctionbody,andyoucan’tprovideanydefaultparametervaluesaspartofthefunctiondeclaration.Forexamplesofconformingtypesthatimplementthemethodrequirementsofaprotocol,seeMethodRequirements.

Todeclareaclassorstaticmethodrequirementinaprotocoldeclaration,markthemethoddeclarationwiththestaticdeclarationmodifier.Structuresandenumerationsthatconformtotheprotocoldeclarethemethodwiththestatickeyword,andclassesthatconformtotheprotocoldeclarethemethodwitheitherthestaticorclasskeyword.Extensionsthataddprotocolconformancetoastructure,enumeration,orclassusethesamekeywordasthetypetheyextenduses.Extensionsthatprovideadefaultimplementationforatypemethodrequirementusethestatickeyword.

SeealsoFunctionDeclaration.

GRAMMAR OF A PROTOCOLMETHOD DECLARAT ION

protocol-method-declaration → function-head function-name generic-parameter-clauseopt function-signature generic-where-clause opt

Page 661: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

ProtocolInitializerDeclarationProtocolsdeclarethatconformingtypesmustimplementaninitializerbyincludingaprotocolinitializerdeclarationinthebodyoftheprotocoldeclaration.Protocolinitializerdeclarationshavethesameformasinitializerdeclarations,excepttheydon’tincludetheinitializer’sbody.

Aconformingtypecansatisfyanonfailableprotocolinitializerrequirementbyimplementinganonfailableinitializeroraninit!failableinitializer.Aconformingtypecansatisfyafailableprotocolinitializerrequirementbyimplementinganykindofinitializer.

Whenaclassimplementsaninitializertosatisfyaprotocol’sinitializerrequirement,theinitializermustbemarkedwiththerequireddeclarationmodifieriftheclassisnotalreadymarkedwiththefinaldeclarationmodifier.

SeealsoInitializerDeclaration.

GRAMMAR OF A PROTOCOL I N I T I A L I ZER DECLARAT ION

protocol-initializer-declaration → initializer-head generic-parameter-clause optparameter-clause throwsopt generic-where-clause opt

protocol-initializer-declaration → initializer-head generic-parameter-clause optparameter-clause rethrows generic-where-clause opt

ProtocolSubscriptDeclarationProtocolsdeclarethatconformingtypesmustimplementasubscriptbyincludingaprotocolsubscriptdeclarationinthebodyoftheprotocoldeclaration.Protocolsubscriptdeclarationshaveaspecialformofasubscriptdeclaration:

subscript( parameters )-> returntype {getset}

Subscriptdeclarationsonlydeclaretheminimumgetterandsetterimplementationrequirementsfortypesthatconformtotheprotocol.Ifthesubscriptdeclarationincludesboththegetandsetkeywords,aconformingtypemustimplementbothagetterandasetterclause.Ifthesubscriptdeclarationincludesonlythegetkeyword,aconformingtypemustimplementatleasta

Page 662: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

getterclauseandoptionallycanimplementasetterclause.

Todeclareastaticsubscriptrequirementinaprotocoldeclaration,markthesubscriptdeclarationwiththestaticdeclarationmodifier.Structuresandenumerationsthatconformtotheprotocoldeclarethesubscriptwiththestatickeyword,andclassesthatconformtotheprotocoldeclarethesubscriptwitheitherthestaticorclasskeyword.Extensionsthataddprotocolconformancetoastructure,enumeration,orclassusethesamekeywordasthetypetheyextenduses.Extensionsthatprovideadefaultimplementationforastaticsubscriptrequirementusethestatickeyword.

SeealsoSubscriptDeclaration.

GRAMMAR OF A PROTOCOLSUBSCR IPT DECLARAT ION

protocol-subscript-declaration → subscript-head subscript-result generic-where-clauseopt getter-setter-keyword-block

ProtocolAssociatedTypeDeclarationProtocolsdeclareassociatedtypesusingtheassociatedtypekeyword.Anassociatedtypeprovidesanaliasforatypethatisusedaspartofaprotocol’sdeclaration.Associatedtypesaresimilartotypeparametersingenericparameterclauses,butthey’reassociatedwithSelfintheprotocolinwhichthey’redeclared.Inthatcontext,Selfreferstotheeventualtypethatconformstotheprotocol.Formoreinformationandexamples,seeAssociatedTypes.

Youuseagenericwhereclauseinaprotocoldeclarationtoaddconstraintstoanassociatedtypesinheritedfromanotherprotocol,withoutredeclaringtheassociatedtypes.Forexample,thedeclarationsofSubProtocolbelowareequivalent:

1 protocolSomeProtocol{

2 associatedtypeSomeType

3 }

4

Page 663: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 protocolSubProtocolA:SomeProtocol{

6 //Thissyntaxproducesawarning.

7 associatedtypeSomeType:Equatable

8 }

9

10 //Thissyntaxispreferred.

11 protocolSubProtocolB:SomeProtocolwhereSomeType:Equatable

{}

SeealsoTypeAliasDeclaration.

GRAMMAR OF A PROTOCOLASSOC IATED TYPE DECLARAT ION

protocol-associated-type-declaration → attributes opt access-level-modifier optassociatedtype typealias-name type-inheritance-clause opt typealias-assignment

opt generic-where-clause opt

InitializerDeclaration

Aninitializerdeclarationintroducesaninitializerforaclass,structure,orenumerationintoyourprogram.Initializerdeclarationsaredeclaredusingtheinitkeywordandhavetwobasicforms.

Structure,enumeration,andclasstypescanhaveanynumberofinitializers,buttherulesandassociatedbehaviorforclassinitializersaredifferent.Unlikestructuresandenumerations,classeshavetwokindsofinitializers:designatedinitializersandconvenienceinitializers,asdescribedinInitialization.

Thefollowingformdeclaresinitializersforstructures,enumerations,anddesignatedinitializersofclasses:

init( parameters ){

statements

}

Page 664: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Adesignatedinitializerofaclassinitializesalloftheclass’spropertiesdirectly.Itcan’tcallanyotherinitializersofthesameclass,andiftheclasshasasuperclass,itmustcalloneofthesuperclass’sdesignatedinitializers.Iftheclassinheritsanypropertiesfromitssuperclass,oneofthesuperclass’sdesignatedinitializersmustbecalledbeforeanyofthesepropertiescanbesetormodifiedinthecurrentclass.

Designatedinitializerscanbedeclaredinthecontextofaclassdeclarationonlyandthereforecan’tbeaddedtoaclassusinganextensiondeclaration.

Initializersinstructuresandenumerationscancallotherdeclaredinitializerstodelegatepartoralloftheinitializationprocess.

Todeclareconvenienceinitializersforaclass,marktheinitializerdeclarationwiththeconveniencedeclarationmodifier.

convenienceinit( parameters ){

statements

}

Convenienceinitializerscandelegatetheinitializationprocesstoanotherconvenienceinitializerortooneoftheclass’sdesignatedinitializers.Thatsaid,theinitializationprocessesmustendwithacalltoadesignatedinitializerthatultimatelyinitializestheclass’sproperties.Convenienceinitializerscan’tcallasuperclass’sinitializers.

Youcanmarkdesignatedandconvenienceinitializerswiththerequireddeclarationmodifiertorequirethateverysubclassimplementtheinitializer.Asubclass’simplementationofthatinitializermustalsobemarkedwiththerequireddeclarationmodifier.

Bydefault,initializersdeclaredinasuperclassarenotinheritedbysubclasses.Thatsaid,ifasubclassinitializesallofitsstoredpropertieswithdefaultvaluesanddoesn’tdefineanyinitializersofitsown,itinheritsallofthesuperclass’sinitializers.Ifthesubclassoverridesallofthesuperclass’sdesignatedinitializers,itinheritsthesuperclass’sconvenienceinitializers.

Aswithmethods,properties,andsubscripts,youneedtomarkoverridden

Page 665: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

designatedinitializerswiththeoverridedeclarationmodifier.

NOTE

Ifyoumarkaninitializerwiththerequireddeclarationmodifier,youdon’talsomarktheinitializerwiththeoverridemodifierwhenyouoverridetherequiredinitializerinasubclass.

Justlikefunctionsandmethods,initializerscanthroworrethrowerrors.Andjustlikefunctionsandmethods,youusethethrowsorrethrowskeywordafteraninitializer’sparameterstoindicatetheappropriatebehavior.

Toseeexamplesofinitializersinvarioustypedeclarations,seeInitialization.

FailableInitializersAfailableinitializerisatypeofinitializerthatproducesanoptionalinstanceoranimplicitlyunwrappedoptionalinstanceofthetypetheinitializerisdeclaredon.Asaresult,afailableinitializercanreturnniltoindicatethatinitializationfailed.

Todeclareafailableinitializerthatproducesanoptionalinstance,appendaquestionmarktotheinitkeywordintheinitializerdeclaration(init?).Todeclareafailableinitializerthatproducesanimplicitlyunwrappedoptionalinstance,appendanexclamationmarkinstead(init!).Theexamplebelowshowsaninit?failableinitializerthatproducesanoptionalinstanceofastructure.

1 structSomeStruct{

2 letproperty:String

3 //producesanoptionalinstanceof'SomeStruct'

4 init?(input:String){

5 ifinput.isEmpty{

6 //discard'self'andreturn'nil'

7 returnnil

8 }

Page 666: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 property=input

10 }

11 }

Youcallaninit?failableinitializerinthesamewaythatyoucallanonfailableinitializer,exceptthatyoumustdealwiththeoptionalityoftheresult.

1 ifletactualInstance=SomeStruct(input:"Hello"){

2 //dosomethingwiththeinstanceof'SomeStruct'

3 }else{

4 //initializationof'SomeStruct'failedandthe

initializerreturned'nil'

5 }

Afailableinitializercanreturnnilatanypointintheimplementationoftheinitializer’sbody.

Afailableinitializercandelegatetoanykindofinitializer.Anonfailableinitializercandelegatetoanothernonfailableinitializerortoaninit!failableinitializer.Anonfailableinitializercandelegatetoaninit?failableinitializerbyforce-unwrappingtheresultofthesuperclass’sinitializer—forexample,bywritingsuper.init()!.

Initializationfailurepropagatesthroughinitializerdelegation.Specifically,ifafailableinitializerdelegatestoaninitializerthatfailsandreturnsnil,thentheinitializerthatdelegatedalsofailsandimplicitlyreturnsnil.Ifanonfailableinitializerdelegatestoaninit!failableinitializerthatfailsandreturnsnil,thenaruntimeerrorisraised(asifyouusedthe!operatortounwrapanoptionalthathasanilvalue).

Afailabledesignatedinitializercanbeoverriddeninasubclassbyanykindofdesignatedinitializer.Anonfailabledesignatedinitializercanbeoverriddeninasubclassbyanonfailabledesignatedinitializeronly.

Formoreinformationandtoseeexamplesoffailableinitializers,seeFailable

Page 667: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Initializers.

GRAMMAR OF AN I N I T I A L I ZER DECLARAT ION

initializer-declaration → initializer-head generic-parameter-clause opt parameter-clausethrowsopt generic-where-clause opt initializer-body

initializer-declaration → initializer-head generic-parameter-clause opt parameter-clauserethrows generic-where-clause opt initializer-body

initializer-head → attributes opt declaration-modifiers opt initinitializer-head → attributes opt declaration-modifiers opt init ?initializer-head → attributes opt declaration-modifiers opt init !initializer-body → code-block

DeinitializerDeclaration

Adeinitializerdeclarationdeclaresadeinitializerforaclasstype.Deinitializerstakenoparametersandhavethefollowingform:

deinit{

statements

}

Adeinitializeriscalledautomaticallywhentherearenolongeranyreferencestoaclassobject,justbeforetheclassobjectisdeallocated.Adeinitializercanbedeclaredonlyinthebodyofaclassdeclaration—butnotinanextensionofaclass—andeachclasscanhaveatmostone.

Asubclassinheritsitssuperclass’sdeinitializer,whichisimplicitlycalledjustbeforethesubclassobjectisdeallocated.Thesubclassobjectisnotdeallocateduntilalldeinitializersinitsinheritancechainhavefinishedexecuting.

Deinitializersarenotcalleddirectly.

Foranexampleofhowtouseadeinitializerinaclassdeclaration,seeDeinitialization.

GRAMMAR OF ADE IN I T I A L I ZER DECLARAT ION

Page 668: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

deinitializer-declaration → attributes opt deinit code-block

ExtensionDeclaration

Anextensiondeclarationallowsyoutoextendthebehaviorofexistingtypes.Extensiondeclarationsaredeclaredusingtheextensionkeywordandhavethefollowingform:

extension typename where requirements {

declarations

}

Thebodyofanextensiondeclarationcontainszeroormoredeclarations.Thesedeclarationscanincludecomputedproperties,computedtypeproperties,instancemethods,typemethods,initializers,subscriptdeclarations,andevenclass,structure,andenumerationdeclarations.Extensiondeclarationscan’tcontaindeinitializerorprotocoldeclarations,storedproperties,propertyobservers,orotherextensiondeclarations.Declarationsinaprotocolextensioncan’tbemarkedfinal.Foradiscussionandseveralexamplesofextensionsthatincludevariouskindsofdeclarations,seeExtensions.

Ifthetypenameisaclass,structure,orenumerationtype,theextensionextendsthattype.Ifthetypenameisaprotocoltype,theextensionextendsalltypesthatconformtothatprotocol.

Extensiondeclarationsthatextendagenerictypeoraprotocolwithassociatedtypescanincluderequirements.Ifaninstanceoftheextendedtypeorofatypethatconformstotheextendedprotocolsatisfiestherequirements,theinstancegainsthebehaviorspecifiedinthedeclaration.

Extensiondeclarationscancontaininitializerdeclarations.Thatsaid,ifthetypeyou’reextendingisdefinedinanothermodule,aninitializerdeclarationmustdelegatetoaninitializeralreadydefinedinthatmoduletoensuremembersofthattypeareproperlyinitialized.

Page 669: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Properties,methods,andinitializersofanexistingtypecan’tbeoverriddeninanextensionofthattype.

Extensiondeclarationscanaddprotocolconformancetoanexistingclass,structure,orenumerationtypebyspecifyingadoptedprotocols:

extension typename : adoptedprotocols where requirements

{

declarations

}

Extensiondeclarationscan’taddclassinheritancetoanexistingclass,andthereforeyoucanspecifyonlyalistofprotocolsafterthetypenameandcolon.

ConditionalConformanceYoucanextendagenerictypetoconditionallyconformtoaprotocol,sothatinstancesofthetypeconformtotheprotocolonlywhencertainrequirementsaremet.Youaddconditionalconformancetoaprotocolbyincludingrequirementsinanextensiondeclaration.

OverriddenRequirementsAren’tUsedinSomeGenericContexts

Insomegenericcontexts,typesthatgetbehaviorfromconditionalconformancetoaprotocoldon’talwaysusethespecializedimplementationsofthatprotocol’srequirements.Toillustratethisbehavior,thefollowingexampledefinestwoprotocolsandagenerictypethatconditionallyconformstobothprotocols.

1 protocolLoggable{

2 funclog()

3 }

4 extensionLoggable{

5 funclog(){

6 print(self)

Page 670: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

7 }

8 }

9

10 protocolTitledLoggable:Loggable{

11 staticvarlogTitle:String{get}

12 }

13 extensionTitledLoggable{

14 funclog(){

15 print("\(Self.logTitle):\(self)")

16 }

17 }

18

19 structPair<T>:CustomStringConvertible{

20 letfirst:T

21 letsecond:T

22 vardescription:String{

23 return"(\(first),\(second))"

24 }

25 }

26

27 extensionPair:LoggablewhereT:Loggable{}

28 extensionPair:TitledLoggablewhereT:TitledLoggable{

29 staticvarlogTitle:String{

30 return"Pairof'\(T.logTitle)'"

31 }

32 }

33

34 extensionString:TitledLoggable{

35 staticvarlogTitle:String{

36 return"String"

Page 671: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

37 }

38 }

ThePairstructureconformstoLoggableandTitledLoggablewheneveritsgenerictypeconformstoLoggableorTitledLoggable,respectively.Intheexamplebelow,oneAndTwoisaninstanceofPair<String>,whichconformstoTitledLoggablebecauseStringconformstoTitledLoggable.Whenthelog()methodiscalledononeAndTwodirectly,thespecializedversioncontainingthetitlestringisused.

1 letoneAndTwo=Pair(first:"one",second:"two")

2 oneAndTwo.log()

3 //Prints"Pairof'String':(one,two)"

However,whenoneAndTwoisusedinagenericcontextorasaninstanceoftheLoggableprotocol,thespecializedversionisn’tused.Swiftpickswhichimplementationoflog()tocallbyconsultingonlytheminimumrequirementsthatPairneedstoconformtoLoggable.Forthisreason,thedefaultimplementationprovidedbytheLoggableprotocolisusedinstead.

1 funcdoSomething<T:Loggable>(withx:T){

2 x.log()

3 }

4 doSomething(with:oneAndTwo)

5 //Prints"(one,two)"

Whenlog()iscalledontheinstancethat’spassedtodoSomething(_:),thecustomizedtitleisomittedfromtheloggedstring.

ProtocolConformanceMustNotBeRedundantAconcretetypecanconformtoaparticularprotocolonlyonce.Swiftmarksredundantprotocolconformancesasanerror.You’relikelytoencounterthiskindoferrorintwokindsofsituations.Thefirstsituationiswhenyouexplicitly

Page 672: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

conformtothesameprotocolmultipletimes,butwithdifferentrequirements.Thesecondsituationiswhenyouimplicitlyinheritfromthesameprotocolmultipletimes.Thesesituationsarediscussedinthesectionsbelow.

ResolvingExplicitRedundancy

Multipleextensionsonaconcretetypecan’taddconformancetothesameprotocol,eveniftheextensions’requirementsaremutuallyexclusive.Thisrestrictionisdemonstratedintheexamplebelow.TwoextensiondeclarationsattempttoaddconditionalconformancetotheSerializableprotocol,oneforforarrayswithIntelements,andoneforarrayswithStringelements.

1 protocolSerializable{

2 funcserialize()->Any

3 }

4

5 extensionArray:SerializablewhereElement==Int{

6 funcserialize()->Any{

7 //implementation

8 }

9 }

10 extensionArray:SerializablewhereElement==String{

11 funcserialize()->Any{

12 //implementation

13 }

14 }

15 //Error:redundantconformanceof'Array<Element>'to

protocol'Serializable'

Ifyouneedtoaddconditionalconformancebasedonmultipleconcretetypes,createanewprotocolthateachtypecanconformtoandusethatprotocolastherequirementwhendeclaringconditionalconformance.

Page 673: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 protocolSerializableInArray{}

2 extensionInt:SerializableInArray{}

3 extensionString:SerializableInArray{}

4

5 extensionArray:SerializablewhereElement:

SerializableInArray{

6 funcserialize()->Any{

7 //implementation

8 }

9 }

ResolvingImplicitRedundancy

Whenaconcretetypeconditionallyconformstoaprotocol,thattypeimplicitlyconformstoanyparentprotocolswiththesamerequirements.

Ifyouneedatypetoconditionallyconformtotwoprotocolsthatinheritfromasingleparent,explicitlydeclareconformancetotheparentprotocol.Thisavoidsimplicitlyconformingtotheparentprotocoltwicewithdifferentrequirements.

ThefollowingexampleexplicitlydeclarestheconditionalconformanceofArraytoLoggabletoavoidaconflictwhendeclaringitsconditionalconformancetobothTitledLoggableandthenewMarkedLoggableprotocol.

1 protocolMarkedLoggable:Loggable{

2 funcmarkAndLog()

3 }

4

5 extensionMarkedLoggable{

6 funcmarkAndLog(){

7 print("----------")

8 log()

Page 674: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

9 }

10 }

11

12 extensionArray:LoggablewhereElement:Loggable{}

13 extensionArray:TitledLoggablewhereElement:TitledLoggable

{

14 staticvarlogTitle:String{

15 return"Arrayof'\(Element.logTitle)'"

16 }

17 }

18 extensionArray:MarkedLoggablewhereElement:MarkedLoggable

{}

WithouttheextensiontoexplicitlydeclareconditionalconformancetoLoggable,theotherArrayextensionswouldimplicitlycreatethesedeclarations,resultinginanerror:

1 extensionArray:LoggablewhereElement:TitledLoggable{}

2 extensionArray:LoggablewhereElement:MarkedLoggable{}

3 //Error:redundantconformanceof'Array<Element>'toprotocol

'Loggable'

GRAMMAR OF AN EXTENS ION DECLARAT ION

extension-declaration → attributes opt access-level-modifier opt extension type-identifier type-inheritance-clause opt generic-where-clause opt extension-body

extension-body → { extension-members opt }extension-members → extension-member extension-members optextension-member → declaration | compiler-control-statement

SubscriptDeclaration

Page 675: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Asubscriptdeclarationallowsyoutoaddsubscriptingsupportforobjectsofaparticulartypeandaretypicallyusedtoprovideaconvenientsyntaxforaccessingtheelementsinacollection,list,orsequence.Subscriptdeclarationsaredeclaredusingthesubscriptkeywordandhavethefollowingform:

subscript( parameters )-> returntype {

get{

statements

}

set( settername ){

statements

}

}

Subscriptdeclarationscanappearonlyinthecontextofaclass,structure,enumeration,extension,orprotocoldeclaration.

Theparametersspecifyoneormoreindexesusedtoaccesselementsofthecorrespondingtypeinasubscriptexpression(forexample,theiintheexpressionobject[i]).Althoughtheindexesusedtoaccesstheelementscanbeofanytype,eachparametermustincludeatypeannotationtospecifythetypeofeachindex.Thereturntypespecifiesthetypeoftheelementbeingaccessed.

Aswithcomputedproperties,subscriptdeclarationssupportreadingandwritingthevalueoftheaccessedelements.Thegetterisusedtoreadthevalue,andthesetterisusedtowritethevalue.Thesetterclauseisoptional,andwhenonlyagetterisneeded,youcanomitbothclausesandsimplyreturntherequestedvaluedirectly.Thatsaid,ifyouprovideasetterclause,youmustalsoprovideagetterclause.

Thesetternameandenclosingparenthesesareoptional.Ifyouprovideasettername,itisusedasthenameoftheparametertothesetter.Ifyoudonotprovideasettername,thedefaultparameternametothesetterisvalue.Thetypeoftheparametertothesetteristhesameasthereturntype.

Youcanoverloadasubscriptdeclarationinthetypeinwhichitisdeclared,as

Page 676: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

longastheparametersorthereturntypedifferfromtheoneyou’reoverloading.Youcanalsooverrideasubscriptdeclarationinheritedfromasuperclass.Whenyoudoso,youmustmarktheoverriddensubscriptdeclarationwiththeoverridedeclarationmodifier.

Subscriptparametersfollowthesamerulesasfunctionparameters,withtwoexceptions.Bydefault,theparametersusedinsubscriptingdon’thaveargumentlabels,unlikefunctions,methods,andinitializers.However,youcanprovideexplicitargumentlabelsusingthesamesyntaxthatfunctions,methods,andinitializersuse.Inaddition,subscriptscan’thavein-outparameters.

Youcanalsodeclaresubscriptsinthecontextofaprotocoldeclaration,asdescribedinProtocolSubscriptDeclaration.

Formoreinformationaboutsubscriptingandtoseeexamplesofsubscriptdeclarations,seeSubscripts.

TypeSubscriptDeclarationsTodeclareasubscriptthat’sexposedbythetype,ratherthanbyinstancesofthetype,markthesubscriptdeclarationwiththestaticdeclarationmodifier.Classescanmarktypecomputedpropertieswiththeclassdeclarationmodifierinsteadtoallowsubclassestooverridethesuperclass’simplementation.Inaclassdeclaration,thestatickeywordhasthesameeffectasmarkingthedeclarationwithboththeclassandfinaldeclarationmodifiers.

GRAMMAR OF A SUBSCR IPT DECLARAT ION

subscript-declaration → subscript-head subscript-result generic-where-clause opt code-block

subscript-declaration → subscript-head subscript-result generic-where-clause opt getter-setter-block

subscript-declaration → subscript-head subscript-result generic-where-clause opt getter-setter-keyword-block

subscript-head → attributes opt declaration-modifiers opt subscript generic-parameter-clause opt parameter-clause

subscript-result → -> attributes opt type

Page 677: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

OperatorDeclaration

Anoperatordeclarationintroducesanewinfix,prefix,orpostfixoperatorintoyourprogramandisdeclaredusingtheoperatorkeyword.

Youcandeclareoperatorsofthreedifferentfixities:infix,prefix,andpostfix.Thefixityofanoperatorspecifiestherelativepositionofanoperatortoitsoperands.

Therearethreebasicformsofanoperatordeclaration,oneforeachfixity.Thefixityoftheoperatorisspecifiedbymarkingtheoperatordeclarationwiththeinfix,prefix,orpostfixdeclarationmodifierbeforetheoperatorkeyword.Ineachform,thenameoftheoperatorcancontainonlytheoperatorcharactersdefinedinOperators.

Thefollowingformdeclaresanewinfixoperator:

infixoperator operatorname : precedencegroup

Aninfixoperatorisabinaryoperatorthatiswrittenbetweenitstwooperands,suchasthefamiliaradditionoperator(+)intheexpression1+2.

Infixoperatorscanoptionallyspecifyaprecedencegroup.Ifyouomittheprecedencegroupforanoperator,Swiftusesthedefaultprecedencegroup,DefaultPrecedence,whichspecifiesaprecedencejusthigherthanTernaryPrecedence.Formoreinformation,seePrecedenceGroupDeclaration.

Thefollowingformdeclaresanewprefixoperator:

prefixoperator operatorname

Aprefixoperatorisaunaryoperatorthatiswrittenimmediatelybeforeitsoperand,suchastheprefixlogicalNOToperator(!)intheexpression!a.

Prefixoperatorsdeclarationsdon’tspecifyaprecedencelevel.Prefixoperatorsarenonassociative.

Thefollowingformdeclaresanewpostfixoperator:

Page 678: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

postfixoperator operatorname

Apostfixoperatorisaunaryoperatorthatiswrittenimmediatelyafteritsoperand,suchasthepostfixforced-unwrapoperator(!)intheexpressiona!.

Aswithprefixoperators,postfixoperatordeclarationsdon’tspecifyaprecedencelevel.Postfixoperatorsarenonassociative.

Afterdeclaringanewoperator,youimplementitbydeclaringastaticmethodthathasthesamenameastheoperator.Thestaticmethodisamemberofoneofthetypeswhosevaluestheoperatortakesasanargument—forexample,anoperatorthatmultipliesaDoublebyanIntisimplementedasastaticmethodoneithertheDoubleorIntstructure.Ifyou’reimplementingaprefixorpostfixoperator,youmustalsomarkthatmethoddeclarationwiththecorrespondingprefixorpostfixdeclarationmodifier.Toseeanexampleofhowtocreateandimplementanewoperator,seeCustomOperators.

GRAMMAR OF AN OPERATOR DECLARAT ION

operator-declaration → prefix-operator-declaration | postfix-operator-declaration | infix-operator-declaration

prefix-operator-declaration → prefix operator operatorpostfix-operator-declaration → postfix operator operatorinfix-operator-declaration → infix operator operator infix-operator-group optinfix-operator-group → : precedence-group-name

PrecedenceGroupDeclaration

Aprecedencegroupdeclarationintroducesanewgroupingforinfixoperatorprecedenceintoyourprogram.Theprecedenceofanoperatorspecifieshowtightlytheoperatorbindstoitsoperands,intheabsenceofgroupingparentheses.

Aprecedencegroupdeclarationhasthefollowingform:

precedencegroup precedencegroupname {

higherThan: lowergroupnames

Page 679: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

lowerThan: highergroupnames

associativity: associativity

assignment: assignment

}

Thelowergroupnamesandhighergroupnameslistsspecifythenewprecedencegroup’srelationtoexistingprecedencegroups.ThelowerThanprecedencegroupattributemayonlybeusedtorefertoprecedencegroupsdeclaredoutsideofthecurrentmodule.Whentwooperatorscompetewitheachotherfortheiroperands,suchasintheexpression2+3*5,theoperatorwiththehigherrelativeprecedencebindsmoretightlytoitsoperands.

NOTE

Precedencegroupsrelatedtoeachotherusinglowergroupnamesandhighergroupnamesmustfitintoasinglerelationalhierarchy,buttheydon’thavetoformalinearhierarchy.Thismeansitispossibletohaveprecedencegroupswithundefinedrelativeprecedence.Operatorsfromthoseprecedencegroupscan’tbeusednexttoeachotherwithoutgroupingparentheses.

Swiftdefinesnumerousprecedencegroupstogoalongwiththeoperatorsprovidedbythestandardlibrary.Forexample,theaddition(+)andsubtraction(-)operatorsbelongtotheAdditionPrecedencegroup,andthemultiplication(*)anddivision(/)operatorsbelongtotheMultiplicationPrecedencegroup.ForacompletelistofprecedencegroupsprovidedbytheSwiftstandardlibrary,seeOperatorDeclarations.

Theassociativityofanoperatorspecifieshowasequenceofoperatorswiththesameprecedencelevelaregroupedtogetherintheabsenceofgroupingparentheses.Youspecifytheassociativityofanoperatorbywritingoneofthecontext-sensitivekeywordsleft,right,ornone—ifyouromittheassociativity,thedefaultisnone.Operatorsthatareleft-associativegroupleft-to-right.Forexample,thesubtractionoperator(-)isleft-associative,sotheexpression4-5-6isgroupedas(4-5)-6andevaluatesto-7.Operatorsthatareright-associativegroupright-to-left,andoperatorsthatarespecifiedwithanassociativityofnonedon’tassociateatall.Nonassociativeoperatorsofthesameprecedencelevelcan’tappearadjacenttoeachtoother.Forexample,the<operatorhasanassociativityofnone,whichmeans1<2<3isnotavalidexpression.

Page 680: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theassignmentofaprecedencegroupspecifiestheprecedenceofanoperatorwhenusedinanoperationthatincludesoptionalchaining.Whensettotrue,anoperatorinthecorrespondingprecedencegroupusesthesamegroupingrulesduringoptionalchainingastheassignmentoperatorsfromthestandardlibrary.Otherwise,whensettofalseoromitted,operatorsintheprecedencegroupfollowsthesameoptionalchainingrulesasoperatorsthatdon’tperformassignment.

GRAMMAR OF A PRECEDENCE GROUP DECLARAT ION

precedence-group-declaration → precedencegroup precedence-group-name {precedence-group-attributes opt }

precedence-group-attributes → precedence-group-attribute precedence-group-attributesopt

precedence-group-attribute → precedence-group-relationprecedence-group-attribute → precedence-group-assignmentprecedence-group-attribute → precedence-group-associativityprecedence-group-relation → higherThan : precedence-group-namesprecedence-group-relation → lowerThan : precedence-group-namesprecedence-group-assignment → assignment : boolean-literalprecedence-group-associativity → associativity : leftprecedence-group-associativity → associativity : rightprecedence-group-associativity → associativity : noneprecedence-group-names → precedence-group-name | precedence-group-name ,

precedence-group-namesprecedence-group-name → identifier

DeclarationModifiers

Declarationmodifiersarekeywordsorcontext-sensitivekeywordsthatmodifythebehaviorormeaningofadeclaration.Youspecifyadeclarationmodifierbywritingtheappropriatekeywordorcontext-sensitivekeywordbetweenadeclaration’sattributes(ifany)andthekeywordthatintroducesthedeclaration.

class

Applythismodifiertoamemberofaclasstoindicatethatthememberisamemberoftheclassitself,ratherthanamemberofinstancesoftheclass.Membersofasuperclassthathavethismodifieranddon’thavethefinalmodifiercanbeoverriddenbysubclasses.

Page 681: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

dynamic

ApplythismodifiertoanymemberofaclassthatcanberepresentedbyObjective-C.Whenyoumarkamemberdeclarationwiththedynamicmodifier,accesstothatmemberisalwaysdynamicallydispatchedusingtheObjective-Cruntime.Accesstothatmemberisneverinlinedordevirtualizedbythecompiler.

BecausedeclarationsmarkedwiththedynamicmodifieraredispatchedusingtheObjective-Cruntime,theymustbemarkedwiththeobjcattribute.

final

Applythismodifiertoaclassortoaproperty,method,orsubscriptmemberofaclass.It’sappliedtoaclasstoindicatethattheclasscan’tbesubclassed.It’sappliedtoaproperty,method,orsubscriptofaclasstoindicatethataclassmembercan’tbeoverriddeninanysubclass.Foranexampleofhowtousethefinalattribute,seePreventingOverrides.

lazy

Applythismodifiertoastoredvariablepropertyofaclassorstructuretoindicatethattheproperty’sinitialvalueiscalculatedandstoredatmostonce,whenthepropertyisfirstaccessed.Foranexampleofhowtousethelazymodifier,seeLazyStoredProperties.

optional

Applythismodifiertoaprotocol’sproperty,method,orsubscriptmemberstoindicatethataconformingtypeisn’trequiredtoimplementthosemembers.

Youcanapplytheoptionalmodifieronlytoprotocolsthataremarkedwiththeobjcattribute.Asaresult,onlyclasstypescanadoptandconformtoaprotocolthatcontainsoptionalmemberrequirements.Formoreinformationabouthowtousetheoptionalmodifierandforguidanceabouthowtoaccessoptionalprotocolmembers—forexample,whenyou’renotsurewhetheraconformingtypeimplementsthem—seeOptionalProtocolRequirements.

Page 682: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

required

Applythismodifiertoadesignatedorconvenienceinitializerofaclasstoindicatethateverysubclassmustimplementthatinitializer.Thesubclass’simplementationofthatinitializermustalsobemarkedwiththerequiredmodifier.

static

Applythismodifiertoamemberofastructure,class,enumeration,orprotocoltoindicatethatthememberisamemberofthetype,ratherthanamemberofinstancesofthattype.Inthescopeofaclassdeclaration,writingthestaticmodifieronamemberdeclarationhasthesameeffectaswritingtheclassandfinalmodifiersonthatmemberdeclaration.However,constanttypepropertiesofaclassareanexception:statichasitsnormal,nonclassmeaningtherebecauseyoucan’twriteclassorfinalonthosedeclarations.

unowned

Applythismodifiertoastoredvariable,constant,orstoredpropertytoindicatethatthevariableorpropertyhasanunownedreferencetotheobjectstoredasitsvalue.Ifyoutrytoaccessthevariableorpropertyaftertheobjecthasbeendeallocated,aruntimeerrorisraised.Likeaweakreference,thetypeofthepropertyorvaluemustbeaclasstype;unlikeaweakreference,thetypeisnon-optional.Foranexampleandmoreinformationabouttheunownedmodifier,seeUnownedReferences.

unowned(safe)

Anexplicitspellingofunowned.

unowned(unsafe)

Applythismodifiertoastoredvariable,constant,orstoredpropertytoindicatethatthevariableorpropertyhasanunownedreferencetotheobjectstoredasitsvalue.Ifyoutrytoaccessthevariableorpropertyaftertheobjecthasbeendeallocated,you’llaccessthememoryatthelocationwheretheobjectusedtobe,whichisamemory-unsafeoperation.Likeaweakreference,thetypeofthepropertyorvaluemustbeaclasstype;unlikea

Page 683: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

weakreference,thetypeisnon-optional.Foranexampleandmoreinformationabouttheunownedmodifier,seeUnownedReferences.

weak

Applythismodifiertoastoredvariableorstoredvariablepropertytoindicatethatthevariableorpropertyhasaweakreferencetotheobjectstoredasitsvalue.Thetypeofthevariableorpropertymustbeanoptionalclasstype.Ifyouaccessthevariableorpropertyaftertheobjecthasbeendeallocated,itsvalueisnil.Foranexampleandmoreinformationabouttheweakmodifier,seeWeakReferences.

AccessControlLevelsSwiftprovidesfivelevelsofaccesscontrol:open,public,internal,fileprivate,andprivate.Youcanmarkadeclarationwithoneoftheaccess-levelmodifiersbelowtospecifythedeclaration’saccesslevel.AccesscontrolisdiscussedindetailinAccessControl.

open

Applythismodifiertoadeclarationtoindicatethedeclarationcanbeaccessedandsubclassedbycodeinthesamemoduleasthedeclaration.Declarationsmarkedwiththeopenaccess-levelmodifiercanalsobeaccessedandsubclassedbycodeinamodulethatimportsthemodulethatcontainsthatdeclaration.

public

Applythismodifiertoadeclarationtoindicatethedeclarationcanbeaccessedandsubclassedbycodeinthesamemoduleasthedeclaration.Declarationsmarkedwiththepublicaccess-levelmodifiercanalsobeaccessed(butnotsubclassed)bycodeinamodulethatimportsthemodulethatcontainsthatdeclaration.

internal

Applythismodifiertoadeclarationtoindicatethedeclarationcanbe

Page 684: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

accessedonlybycodeinthesamemoduleasthedeclaration.Bydefault,mostdeclarationsareimplicitlymarkedwiththeinternalaccess-levelmodifier.

fileprivate

Applythismodifiertoadeclarationtoindicatethedeclarationcanbeaccessedonlybycodeinthesamesourcefileasthedeclaration.

private

Applythismodifiertoadeclarationtoindicatethedeclarationcanbeaccessedonlybycodewithinthedeclaration’simmediateenclosingscope.

Forthepurposeofaccesscontrol,extensionstothesametypethatareinthesamefileshareanaccess-controlscope.Ifthetypetheyextendisalsointhesamefile,theysharethetype’saccess-controlscope.Privatemembersdeclaredinthetype’sdeclarationcanbeaccessedfromextensions,andprivatemembersdeclaredinoneextensioncanbeaccessedfromotherextensionsandfromthetype’sdeclaration.

Eachaccess-levelmodifieraboveoptionallyacceptsasingleargument,whichconsistsofthesetkeywordenclosedinparentheses(forexample,private(set)).Usethisformofanaccess-levelmodifierwhenyouwanttospecifyanaccesslevelforthesetterofavariableorsubscriptthat’slessthanorequaltotheaccesslevelofthevariableorsubscriptitself,asdiscussedinGettersandSetters.

GRAMMAR OF ADECLARAT ION MOD IF I ER

declaration-modifier → class | convenience | dynamic | final | infix | lazy |optional | override | postfix | prefix | required | static | unowned |unowned ( safe ) | unowned ( unsafe ) | weak

declaration-modifier → access-level-modifierdeclaration-modifier → mutation-modifierdeclaration-modifiers → declaration-modifier declaration-modifiers optaccess-level-modifier → private | private ( set )access-level-modifier → fileprivate | fileprivate ( set )access-level-modifier → internal | internal ( set )access-level-modifier → public | public ( set )access-level-modifier → open | open ( set )mutation-modifier → mutating | nonmutating

Page 685: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Attributes

TherearetwokindsofattributesinSwift—thosethatapplytodeclarationsandthosethatapplytotypes.Anattributeprovidesadditionalinformationaboutthedeclarationortype.Forexample,thediscardableResultattributeonafunctiondeclarationindicatesthat,althoughthefunctionreturnsavalue,thecompilershouldn’tgenerateawarningifthereturnvalueisunused.

Youspecifyanattributebywritingthe@symbolfollowedbytheattribute’snameandanyargumentsthattheattributeaccepts:

@ attributename

@ attributename ( attributearguments )

Somedeclarationattributesacceptargumentsthatspecifymoreinformationabouttheattributeandhowitappliestoaparticulardeclaration.Theseattributeargumentsareenclosedinparentheses,andtheirformatisdefinedbytheattributetheybelongto.

DeclarationAttributes

Youcanapplyadeclarationattributetodeclarationsonly.

availableApplythisattributetoindicateadeclaration’slifecyclerelativetocertainSwiftlanguageversionsorcertainplatformsandoperatingsystemversions.

Theavailableattributealwaysappearswithalistoftwoormorecomma-separatedattributearguments.Theseargumentsbeginwithoneofthefollowingplatformorlanguagenames:

Page 686: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

iOS

iOSApplicationExtension

macOS

macOSApplicationExtension

watchOS

watchOSApplicationExtension

tvOS

tvOSApplicationExtension

swift

Youcanalsouseanasterisk(*)toindicatetheavailabilityofthedeclarationonalloftheplatformnameslistedabove.AnavailableattributethatspecifiesavailabilityusingaSwiftversionnumbercan’tusetheasterisk.

Theremainingargumentscanappearinanyorderandspecifyadditionalinformationaboutthedeclaration’slifecycle,includingimportantmilestones.

Theunavailableargumentindicatesthatthedeclarationisn’tavailableonthespecifiedplatform.Thisargumentcan’tbeusedwhenspecifyingSwiftversionavailability.

Theintroducedargumentindicatesthefirstversionofthespecifiedplatformorlanguageinwhichthedeclarationwasintroduced.Ithasthefollowingform:

introduced: versionnumber

Theversionnumberconsistsofonetothreepositiveintegers,separatedbyperiods.

Thedeprecatedargumentindicatesthefirstversionofthespecified

Page 687: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

platformorlanguageinwhichthedeclarationwasdeprecated.Ithasthefollowingform:

deprecated: versionnumber

Theoptionalversionnumberconsistsofonetothreepositiveintegers,separatedbyperiods.Omittingtheversionnumberindicatesthatthedeclarationiscurrentlydeprecated,withoutgivinganyinformationaboutwhenthedeprecationoccurred.Ifyouomittheversionnumber,omitthecolon(:)aswell.

Theobsoletedargumentindicatesthefirstversionofthespecifiedplatformorlanguageinwhichthedeclarationwasobsoleted.Whenadeclarationisobsoleted,it’sremovedfromthespecifiedplatformorlanguageandcannolongerbeused.Ithasthefollowingform:

obsoleted: versionnumber

Theversionnumberconsistsofonetothreepositiveintegers,separatedbyperiods.

Themessageargumentprovidesatextualmessagethatthecompilerdisplayswhenemittingawarningorerrorabouttheuseofadeprecatedorobsoleteddeclaration.Ithasthefollowingform:

message: message

Themessageconsistsofastringliteral.

Therenamedargumentprovidesatextualmessagethatindicatesthenewnameforadeclarationthat’sbeenrenamed.Thecompilerdisplaysthenewnamewhenemittinganerrorabouttheuseofarenameddeclaration.Ithasthefollowingform:

renamed: newname

Thenewnameconsistsofastringliteral.

Page 688: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Youcanapplytheavailableattributewiththerenamedandunavailableargumentstoatypealiasdeclaration,asshownbelow,toindicatethatthenameofadeclarationchangedbetweenreleasesofaframeworkorlibrary.Thiscombinationresultsinacompile-timeerrorthatthedeclarationhasbeenrenamed.

1 //Firstrelease

2 protocolMyProtocol{

3 //protocoldefinition

4 }

1 //SubsequentreleaserenamesMyProtocol

2 protocolMyRenamedProtocol{

3 //protocoldefinition

4 }

5

6 @available(*,unavailable,renamed:"MyRenamedProtocol")

7 typealiasMyProtocol=MyRenamedProtocol

Youcanapplymultipleavailableattributesonasingledeclarationtospecifythedeclaration’savailabilityondifferentplatformsanddifferentversionsofSwift.Thedeclarationthattheavailableattributeappliestoisignorediftheattributespecifiesaplatformorlanguageversionthatdoesn’tmatchthecurrenttarget.Ifyouusemultipleavailableattributes,theeffectiveavailabilityisthecombinationoftheplatformandSwiftavailabilities.

Ifanavailableattributeonlyspecifiesanintroducedargumentinadditiontoaplatformorlanguagenameargument,youcanusethefollowingshorthandsyntaxinstead:

@available( platformname versionnumber ,*)

@available(swift versionnumber )

Theshorthandsyntaxforavailableattributesconciselyexpressesavailability

Page 689: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

formultipleplatforms.Althoughthetwoformsarefunctionallyequivalent,theshorthandformispreferredwheneverpossible.

1 @available(iOS10.0,macOS10.12,*)

2 classMyClass{

3 //classdefinition

4 }

AnavailableattributethatspecifiesavailabilityusingaSwiftversionnumbercan’tadditionallyspecifyadeclaration’splatformavailability.Instead,useseparateavailableattributestospecifyaSwiftversionavailabilityandoneormoreplatformavailabilities.

1 @available(swift3.0.2)

2 @available(macOS10.12,*)

3 structMyStruct{

4 //structdefinition

5 }

discardableResultApplythisattributetoafunctionormethoddeclarationtosuppressthecompilerwarningwhenthefunctionormethodthatreturnsavalueiscalledwithoutusingitsresult.

dynamicCallableApplythisattributetoaclass,structure,enumeration,orprotocoltotreatinstancesofthetypeascallablefunctions.ThetypemustimplementeitheradynamicallyCall(withArguments:)method,adynamicallyCall(withKeywordArguments:)method,orboth.

Youcancallaninstanceofadynamicallycallabletypeasifit’safunctionthat

Page 690: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

takesanynumberofarguments.

1 @dynamicCallable

2 structTelephoneExchange{

3 funcdynamicallyCall(withArgumentsphoneNumber:[Int]){

4 ifphoneNumber==[4,1,1]{

5 print("GetSwifthelponforums.swift.org")

6 }else{

7 print("Unrecognizednumber")

8 }

9 }

10 }

11

12 letdial=TelephoneExchange()

13

14 //Useadynamicmethodcall.

15 dial(4,1,1)

16 //Prints"GetSwifthelponforums.swift.org"

17

18 dial(8,6,7,5,3,0,9)

19 //Prints"Unrecognizednumber"

20

21 //Calltheunderlyingmethoddirectly.

22 dial.dynamicallyCall(withArguments:[4,1,1])

ThedeclarationofthedynamicallyCall(withArguments:)methodmusthaveasingleparameterthatconformstotheExpressibleByArrayLiteralprotocol—like[Int]intheexampleabove.Thereturntypecanbeanytype.

YoucanincludelabelsinadynamicmethodcallifyouimplementthedynamicallyCall(withKeywordArguments:)method.

Page 691: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 @dynamicCallable

2 structRepeater{

3 funcdynamicallyCall(withKeywordArgumentspairs:

KeyValuePairs<String,Int>)->String{

4 returnpairs

5 .map{label,countin

6 repeatElement(label,count:

count).joined(separator:"")

7 }

8 .joined(separator:"\n")

9 }

10 }

11

12 letrepeatLabels=Repeater()

13 print(repeatLabels(a:1,b:2,c:3,b:2,a:1))

14 //a

15 //bb

16 //ccc

17 //bb

18 //a

ThedeclarationofthedynamicallyCall(withKeywordArguments:)methodmusthaveasingleparameterthatconformstotheExpressibleByDictionaryLiteralprotocol,andthereturntypecanbeanytype.Theparameter’sKeymustbeExpressibleByStringLiteral.ThepreviousexampleusesKeyValuePairsastheparametertypesothatcallerscanincludeduplicateparameterlabels—aandbappearmultipletimesinthecalltorepeat.

IfyouimplementbothdynamicallyCallmethods,dynamicallyCall(withKeywordArguments:)iscalledwhenthemethodcallincludeskeywordarguments.Inallothercases,dynamicallyCall(withArguments:)iscalled.

Page 692: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

YoucanonlycalladynamicallycallableinstancewithargumentsandareturnvaluethatmatchthetypesyouspecifyinoneofyourdynamicallyCallmethodimplementations.Thecallinthefollowingexampledoesn’tcompilebecausethereisn’tanimplementationofdynamicallyCall(withArguments:)thattakesKeyValuePairs<String,String>.

repeatLabels(a:"four")//Error

dynamicMemberLookupApplythisattributetoaclass,structure,enumeration,orprotocoltoenablememberstobelookedupbynameatruntime.Thetypemustimplementasubscript(dynamicMemberLookup:)subscript.

Inanexplicitmemberexpression,ifthereisn’tacorrespondingdeclarationforthenamedmember,theexpressionisunderstoodasacalltothetype’ssubscript(dynamicMemberLookup:)subscript,passinginformationaboutthememberastheargument.Thesubscriptcanacceptaparameterthat’seitherakeypathoramembername;ifyouimplementbothsubscripts,thesubscriptthattakeskeypathargumentisused.

Animplementationofsubscript(dynamicMemberLookup:)canacceptkeypathsusinganargumentoftypeKeyPath,WritableKeyPath,orReferenceWritableKeyPath.ItcanacceptmembernamesusinganargumentofatypethatconformstotheExpressibleByStringLiteralprotocol—inmostcases,String.Thesubscript’sreturntypecanbeanytype.

Dynamicmemberlookupbymembernamecanbeusedtocreateawrappertypearounddatathatcan’tbetypecheckedatcompiletime,suchaswhenbridgingdatafromotherlanguagesintoSwift.Forexample:

1 @dynamicMemberLookup

2 structDynamicStruct{

3 letdictionary=["someDynamicMember":325,

4 "someOtherMember":787]

Page 693: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

5 subscript(dynamicMembermember:String)->Int{

6 returndictionary[member]??1054

7 }

8 }

9 lets=DynamicStruct()

10

11 //Usedynamicmemberlookup.

12 letdynamic=s.someDynamicMember

13 print(dynamic)

14 //Prints"325"

15

16 //Calltheunderlyingsubscriptdirectly.

17 letequivalent=s[dynamicMember:"someDynamicMember"]

18 print(dynamic==equivalent)

19 //Prints"true"

Dynamicmemberlookupbykeypathcanbeusedtoimplementawrappertypeinawaythatsupportscompile-timetypechecking.Forexample:

1 structPoint{varx,y:Int}

2

3 @dynamicMemberLookup

4 structPassthroughWrapper<Value>{

5 varvalue:Value

6 subscript<T>(dynamicMembermember:KeyPath<Value,T>)->T

{

7 get{returnvalue[keyPath:member]}

8 }

9 }

10

Page 694: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

11 letpoint=Point(x:381,y:431)

12 letwrapper=PassthroughWrapper(value:point)

13 print(wrapper.x)

frozenApplythisattributetoastructureorenumerationdeclarationtorestrictthekindsofchangesyoucanmaketothetype.Thisattributeisallowedonlywhencompilinginlibraryevolutionmode.Futureversionsofthelibrarycan’tchangethedeclarationbyadding,removing,orreorderinganenumeration’scasesorastructure’sstoredinstanceproperties.Thesechangesareallowedonnonfrozentypes,buttheybreakABIcompatibilityforfrozentypes.

NOTE

Whenthecompilerisn’tinlibraryevolutionmode,allstructuresandenumerationsareimplicitlyfrozen,andyoucan’tusethisattribute.

Inlibraryevolutionmode,codethatinteractswithmembersofnonfrozenstructuresandenumerationsiscompiledinawaythatallowsittocontinueworkingwithoutrecompilingevenifafutureversionofthelibraryadds,removes,orreorderssomeofthattype’smembers.Thecompilermakesthispossibleusingtechniqueslikelookingupinformationatruntimeandaddingalayerofindirection.Markingastructureorenumerationasfrozengivesupthisflexibilitytogainperformance:Futureversionsofthelibrarycanmakeonlylimitedchangestothetype,butthecompilercanmakeadditionaloptimizationsincodethatinteractswiththetype’smembers.

Frozentypes,thetypesofthestoredpropertiesoffrozenstructures,andtheassociatedvaluesoffrozenenumerationcasesmustbepublicormarkedwiththeusableFromInlineattribute.Thepropertiesofafrozenstructurecan’thavepropertyobservers,andexpressionsthatprovidetheinitialvalueforstoredinstancepropertiesmustfollowthesamerestrictionsasinlinablefunctions,asdiscussedininlinable.

Toenablelibraryevolutionmodeonthecommandline,passthe-enable-

Page 695: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

library-evolutionoptiontotheSwiftcompiler.ToenableitinXcode,setthe“BuildLibrariesforDistribution”buildsetting(BUILD_LIBRARY_FOR_DISTRIBUTION)toYes,asdescribedinXcodeHelp.

Aswitchstatementoverafrozenenumerationdoesn’trequireadefaultcase,asdiscussedinSwitchingOverFutureEnumerationCases.Includingadefaultor@unknowndefaultcasewhenswitchingoverafrozenenumerationproducesawarningbecausethatcodeisneverexecuted.

GKInspectableApplythisattributetoexposeacustomGameplayKitcomponentpropertytotheSpriteKiteditorUI.Applyingthisattributealsoimpliestheobjcattribute.

inlinableApplythisattributetoafunction,method,computedproperty,subscript,convenienceinitializer,ordeinitializerdeclarationtoexposethatdeclaration’simplementationaspartofthemodule’spublicinterface.Thecompilerisallowedtoreplacecallstoaninlinablesymbolwithacopyofthesymbol’simplementationatthecallsite.

Inlinablecodecaninteractwithpublicsymbolsdeclaredinanymodule,anditcaninteractwithinternalsymbolsdeclaredinthesamemodulethataremarkedwiththeusableFromInlineattribute.Inlinablecodecan’tinteractwithprivateorfileprivatesymbols.

Thisattributecan’tbeappliedtodeclarationsthatarenestedinsidefunctionsortofileprivateorprivatedeclarations.Functionsandclosuresthataredefinedinsideaninlinablefunctionareimplicitlyinlinable,eventhoughtheycan’tbemarkedwiththisattribute.

nonobjcApplythisattributetoamethod,property,subscript,orinitializerdeclarationto

Page 696: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

suppressanimplicitobjcattribute.ThenonobjcattributetellsthecompilertomakethedeclarationunavailableinObjective-Ccode,eventhoughit’spossibletorepresentitinObjective-C.

Applyingthisattributetoanextensionhasthesameeffectasapplyingittoeverymemberofthatextensionthatisn’texplicitlymarkedwiththeobjcattribute.

Youusethenonobjcattributetoresolvecircularityforbridgingmethodsinaclassmarkedwiththeobjcattribute,andtoallowoverloadingofmethodsandinitializersinaclassmarkedwiththeobjcattribute.

Amethodmarkedwiththenonobjcattributecan’toverrideamethodmarkedwiththeobjcattribute.However,amethodmarkedwiththeobjcattributecanoverrideamethodmarkedwiththenonobjcattribute.Similarly,amethodmarkedwiththenonobjcattributecan’tsatisfyaprotocolrequirementforamethodmarkedwiththeobjcattribute.

NSApplicationMainApplythisattributetoaclasstoindicatethatit’stheapplicationdelegate.UsingthisattributeisequivalenttocallingtheNSApplicationMain(_:_:)function.

Ifyoudon’tusethisattribute,supplyamain.swiftfilewithcodeatthetoplevelthatcallstheNSApplicationMain(_:_:)functionasfollows:

1 importAppKit

2 NSApplicationMain(CommandLine.argc,CommandLine.unsafeArgv)

NSCopyingApplythisattributetoastoredvariablepropertyofaclass.Thisattributecausestheproperty’ssettertobesynthesizedwithacopyoftheproperty’svalue—returnedbythecopyWithZone(_:)method—insteadofthevalueofthepropertyitself.ThetypeofthepropertymustconformtotheNSCopyingprotocol.

Page 697: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheNSCopyingattributebehavesinawaysimilartotheObjective-Ccopypropertyattribute.

NSManagedApplythisattributetoaninstancemethodorstoredvariablepropertyofaclassthatinheritsfromNSManagedObjecttoindicatethatCoreDatadynamicallyprovidesitsimplementationatruntime,basedontheassociatedentitydescription.ForapropertymarkedwiththeNSManagedattribute,CoreDataalsoprovidesthestorageatruntime.Applyingthisattributealsoimpliestheobjcattribute.

objcApplythisattributetoanydeclarationthatcanberepresentedinObjective-C—forexample,nonnestedclasses,protocols,nongenericenumerations(constrainedtointegerraw-valuetypes),propertiesandmethods(includinggettersandsetters)ofclasses,protocolsandoptionalmembersofaprotocol,initializers,andsubscripts.TheobjcattributetellsthecompilerthatadeclarationisavailabletouseinObjective-Ccode.

Applyingthisattributetoanextensionhasthesameeffectasapplyingittoeverymemberofthatextensionthatisn’texplicitlymarkedwiththenonobjcattribute.

ThecompilerimplicitlyaddstheobjcattributetosubclassesofanyclassdefinedinObjective-C.However,thesubclassmustnotbegeneric,andmustnotinheritfromanygenericclasses.Youcanexplicitlyaddtheobjcattributetoasubclassthatmeetsthesecriteria,tospecifyitsObjective-Cnameasdiscussedbelow.Protocolsthataremarkedwiththeobjcattributecan’tinheritfromprotocolsthataren’tmarkedwiththisattribute.

Theobjcattributeisalsoimplicitlyaddedinthefollowingcases:

Thedeclarationisanoverrideinasubclass,andthesuperclass’sdeclarationhastheobjcattribute.

Page 698: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Thedeclarationsatisfiesarequirementfromaprotocolthathastheobjcattribute.

ThedeclarationhastheIBAction,IBSegueAction,IBOutlet,IBDesignable,IBInspectable,NSManaged,orGKInspectableattribute.

Ifyouapplytheobjcattributetoanenumeration,eachenumerationcaseisexposedtoObjective-Ccodeastheconcatenationoftheenumerationnameandthecasename.Thefirstletterofthecasenameiscapitalized.Forexample,acasenamedvenusinaSwiftPlanetenumerationisexposedtoObjective-CcodeasacasenamedPlanetVenus.

Theobjcattributeoptionallyacceptsasingleattributeargument,whichconsistsofanidentifier.TheidentifierspecifiesthenametobeexposedtoObjective-Cfortheentitythattheobjcattributeappliesto.Youcanusethisargumenttonameclasses,enumerations,enumerationcases,protocols,methods,getters,setters,andinitializers.IfyouspecifytheObjective-Cnameforaclass,protocol,orenumeration,includeathree-letterprefixonthename,asdescribedinConventionsinProgrammingwithObjective-C.TheexamplebelowexposesthegetterfortheenabledpropertyoftheExampleClasstoObjective-CcodeasisEnabledratherthanjustasthenameofthepropertyitself.

1 classExampleClass:NSObject{

2 @objcvarenabled:Bool{

3 @objc(isEnabled)get{

4 //Returntheappropriatevalue

5 }

6 }

7 }

objcMembersApplythisattributetoaclassdeclaration,toimplicitlyapplytheobjcattributetoallObjective-Ccompatiblemembersoftheclass,itsextensions,itssubclasses,andalloftheextensionsofitssubclasses.

Page 699: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Mostcodeshouldusetheobjcattributeinstead,toexposeonlythedeclarationsthatareneeded.Ifyouneedtoexposemanydeclarations,youcangrouptheminanextensionthathastheobjcattribute.TheobjcMembersattributeisaconvenienceforlibrariesthatmakeheavyuseoftheintrospectionfacilitiesoftheObjective-Cruntime.Applyingtheobjcattributewhenitisn’tneededcanincreaseyourbinarysizeandadverselyaffectperformance.

propertyWrapperApplythisattributetoaclass,structure,orenumerationdeclarationtousethattypeasapropertywrapper.Whenyouapplythisattributetoatype,youcreateacustomattributewiththesamenameasthetype.Applythatnewattributetoapropertyofaclass,structure,orenumerationtowrapaccesstothepropertythroughaninstanceofthewrappertype.Localandglobalvariablescan’tusepropertywrappers.

ThewrappermustdefineawrappedValueinstanceproperty.Thewrappedvalueofthepropertyisthevaluethatthegetterandsetterforthispropertyexpose.Inmostcases,wrappedValueisacomputedvalue,butitcanbeastoredvalueinstead.Thewrapperisresponsiblefordefiningandmanaginganyunderlyingstorageneededbyitswrappedvalue.Thecompilersynthesizesstoragefortheinstanceofthewrappertypebyprefixingthenameofthewrappedpropertywithanunderscore(_)—forexample,thewrapperforsomePropertyisstoredas_someProperty.Thesynthesizedstorageforthewrapperhasanaccesscontrollevelofprivate.

ApropertythathasapropertywrappercanincludewillSetanddidSetblocks,butitcan’toverridethecompiler-synthesizedgetorsetblocks.

Swiftprovidestwoformsofsyntacticsugarforinitializationofapropertywrapper.Youcanuseassignmentsyntaxinthedefinitionofawrappedvaluetopasstheexpressionontheright-handsideoftheassignmentastheargumenttothewrappedValueparameterofthepropertywrapper’sinitializer.Youcanalsoprovideargumentstotheattributewhenyouapplyittoaproperty,andthoseargumentsarepassedtothepropertywrapper’sinitializer.Forexample,inthecodebelow,SomeStructcallseachoftheinitializersthatSomeWrapperdefines.

Page 700: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

1 @propertyWrapper

2 structSomeWrapper{

3 varwrappedValue:Int

4 varsomeValue:Double

5 init(){

6 self.wrappedValue=100

7 self.someValue=12.3

8 }

9 init(wrappedValue:Int){

10 self.wrappedValue=wrappedValue

11 self.someValue=45.6

12 }

13 init(wrappedValuevalue:Int,custom:Double){

14 self.wrappedValue=value

15 self.someValue=custom

16 }

17 }

18

19 structSomeStruct{

20 //Usesinit()

21 @SomeWrappervara:Int

22

23 //Usesinit(wrappedValue:)

24 @SomeWrappervarb=10

25

26 //Bothuseinit(wrappedValue:custom:)

27 @SomeWrapper(custom:98.7)varc=30

28 @SomeWrapper(wrappedValue:30,custom:98.7)vard

29 }

Page 701: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Theprojectedvalueforawrappedpropertyisasecondvaluethatapropertywrappercanusetoexposeadditionalfunctionality.Theauthorofapropertywrappertypeisresponsiblefordeterminingthemeaningofitsprojectedvalueanddefiningtheinterfacethattheprojectedvalueexposes.Toprojectavaluefromapropertywrapper,defineaprojectedValueinstancepropertyonthewrappertype.Thecompilersynthesizesanidentifierfortheprojectedvaluebyprefixingthenameofthewrappedpropertywithadollarsign($)—forexample,theprojectedvalueforsomePropertyis$someProperty.Theprojectedvaluehasthesameaccesscontrollevelastheoriginalwrappedproperty.

1 @propertyWrapper

2 structWrapperWithProjection{

3 varwrappedValue:Int

4 varprojectedValue:SomeProjection{

5 returnSomeProjection(wrapper:self)

6 }

7 }

8 structSomeProjection{

9 varwrapper:WrapperWithProjection

10 }

11

12 structSomeStruct{

13 @WrapperWithProjectionvarx=123

14 }

15 lets=SomeStruct()

16 s.x//Intvalue

17 s.$x//SomeProjectionvalue

18 s.$x.wrapper//WrapperWithProjectionvalue

requires_stored_property_initsApplythisattributetoaclassdeclarationtorequireallstoredpropertieswithin

Page 702: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

theclasstoprovidedefaultvaluesaspartoftheirdefinitions.ThisattributeisinferredforanyclassthatinheritsfromNSManagedObject.

testableApplythisattributetoanimportdeclarationtoimportthatmodulewithchangestoitsaccesscontrolthatsimplifytestingthemodule’scode.Entitiesintheimportedmodulethataremarkedwiththeinternalaccess-levelmodifierareimportedasiftheyweredeclaredwiththepublicaccess-levelmodifier.Classesandclassmembersthataremarkedwiththeinternalorpublicaccess-levelmodifierareimportedasiftheyweredeclaredwiththeopenaccess-levelmodifier.Theimportedmodulemustbecompiledwithtestingenabled.

UIApplicationMainApplythisattributetoaclasstoindicatethatit’stheapplicationdelegate.UsingthisattributeisequivalenttocallingtheUIApplicationMainfunctionandpassingthisclass’snameasthenameofthedelegateclass.

Ifyoudon’tusethisattribute,supplyamain.swiftfilewithcodeatthetoplevelthatcallstheUIApplicationMain(_:_:_:_:)function.Forexample,ifyourappusesacustomsubclassofUIApplicationasitsprincipalclass,calltheUIApplicationMain(_:_:_:_:)functioninsteadofusingthisattribute.

usableFromInlineApplythisattributetoafunction,method,computedproperty,subscript,initializer,ordeinitializerdeclarationtoallowthatsymboltobeusedininlinablecodethat’sdefinedinthesamemoduleasthedeclaration.Thedeclarationmusthavetheinternalaccesslevelmodifier.AstructureorclassmarkedusableFromInlinecanuseonlytypesthatarepublicorusableFromInlineforitsproperties.AnenumerationmarkedusableFromInlinecanuseonlytypesthatarepublicorusableFromInlinefortherawvaluesandassociatedvaluesofitscases.

Likethepublicaccesslevelmodifier,thisattributeexposesthedeclarationas

Page 703: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

partofthemodule’spublicinterface.Unlikepublic,thecompilerdoesn’tallowdeclarationsmarkedwithusableFromInlinetobereferencedbynameincodeoutsidethemodule,eventhoughthedeclaration’ssymbolisexported.However,codeoutsidethemodulemightstillbeabletointeractwiththedeclaration’ssymbolbyusingruntimebehavior.

Declarationsmarkedwiththeinlinableattributeareimplicitlyusablefrominlinablecode.AlthougheitherinlinableorusableFromInlinecanbeappliedtointernaldeclarations,applyingbothattributesisanerror.

warn_unqualified_accessApplythisattributetoatop-levelfunction,instancemethod,orclassorstaticmethodtotriggerwarningswhenthatfunctionormethodisusedwithoutaprecedingqualifier,suchasamodulename,typename,orinstancevariableorconstant.Usethisattributetohelpdiscourageambiguitybetweenfunctionswiththesamenamethatareaccessiblefromthesamescope.

Forexample,theSwiftstandardlibraryincludesbothatop-levelmin(_:_:)functionandamin()methodforsequenceswithcomparableelements.Thesequencemethodisdeclaredwiththewarn_unqualified_accessattributetohelpreduceconfusionwhenattemptingtouseoneortheotherfromwithinaSequenceextension.

DeclarationAttributesUsedbyInterfaceBuilderInterfaceBuilderattributesaredeclarationattributesusedbyInterfaceBuildertosynchronizewithXcode.SwiftprovidesthefollowingInterfaceBuilderattributes:IBAction,IBSegueAction,IBOutlet,IBDesignable,andIBInspectable.TheseattributesareconceptuallythesameastheirObjective-Ccounterparts.

YouapplytheIBOutletandIBInspectableattributestopropertydeclarationsofaclass.YouapplytheIBActionandIBSegueActionattributetomethoddeclarationsofaclassandtheIBDesignableattributetoclassdeclarations.

ApplyingtheIBAction,IBSegueAction,IBOutlet,IBDesignable,or

Page 704: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

IBInspectableattributealsoimpliestheobjcattribute.

TypeAttributes

Youcanapplytypeattributestotypesonly.

autoclosureApplythisattributetodelaytheevaluationofanexpressionbyautomaticallywrappingthatexpressioninaclosurewithnoarguments.Youapplyittoaparameter’stypeinamethodorfunctiondeclaration,foraparameterwhosetypeisafunctiontypethattakesnoargumentsandthatreturnsavalueofthetypeoftheexpression.Foranexampleofhowtousetheautoclosureattribute,seeAutoclosuresandFunctionType.

conventionApplythisattributetothetypeofafunctiontoindicateitscallingconventions.

Theconventionattributealwaysappearswithoneofthefollowingarguments:

TheswiftargumentindicatesaSwiftfunctionreference.ThisisthestandardcallingconventionforfunctionvaluesinSwift.

TheblockargumentindicatesanObjective-Ccompatibleblockreference.Thefunctionvalueisrepresentedasareferencetotheblockobject,whichisanid-compatibleObjective-Cobjectthatembedsitsinvocationfunctionwithintheobject.TheinvocationfunctionusestheCcallingconvention.

ThecargumentindicatesaCfunctionreference.ThefunctionvaluecarriesnocontextandusestheCcallingconvention.

Withafewexceptions,afunctionofanycallingconventioncanbeusedwhenafunctionanyothercallingconventionisneeded.Anongenericglobalfunction,a

Page 705: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

localfunctionthatdoesn’tcaptureanylocalvariablesoraclosurethatdoesn’tcaptureanylocalvariablescanbeconvertedtotheCcallingconvention.OtherSwiftfunctionscan’tbeconvertedtotheCcallingconvention.AfunctionwiththeObjective-Cblockcallingconventioncan’tbeconvertedtotheCcallingconvention.

escapingApplythisattributetoaparameter’stypeinamethodorfunctiondeclarationtoindicatethattheparameter’svaluecanbestoredforlaterexecution.Thismeansthatthevalueisallowedtooutlivethelifetimeofthecall.Functiontypeparameterswiththeescapingtypeattributerequireexplicituseofself.forpropertiesormethods.Foranexampleofhowtousetheescapingattribute,seeEscapingClosures.

SwitchCaseAttributes

Youcanapplyswitchcaseattributestoswitchcasesonly.

unknownApplythisattributetoaswitchcasetoindicatethatitisn’texpectedtobematchedbyanycaseoftheenumerationthat’sknownatthetimethecodeiscompiled.Foranexampleofhowtousetheunknownattribute,seeSwitchingOverFutureEnumerationCases.

GRAMMAR OF AN ATTR IBUTE

attribute → @ attribute-name attribute-argument-clause optattribute-name → identifierattribute-argument-clause → ( balanced-tokens opt )attributes → attribute attributes optbalanced-tokens → balanced-token balanced-tokens optbalanced-token → ( balanced-tokens opt )balanced-token → [ balanced-tokens opt ]

Page 706: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

balanced-token → { balanced-tokens opt }balanced-token → Anyidentifier,keyword,literal,oroperatorbalanced-token → Anypunctuationexcept ( , ) , [ , ] , { ,or }

Page 707: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Patterns

Apatternrepresentsthestructureofasinglevalueoracompositevalue.Forexample,thestructureofatuple(1,2)isacomma-separatedlistoftwoelements.Becausepatternsrepresentthestructureofavalueratherthananyoneparticularvalue,youcanmatchthemwithavarietyofvalues.Forinstance,thepattern(x,y)matchesthetuple(1,2)andanyothertwo-elementtuple.Inadditiontomatchingapatternwithavalue,youcanextractpartorallofacompositevalueandbindeachparttoaconstantorvariablename.

InSwift,therearetwobasickindsofpatterns:thosethatsuccessfullymatchanykindofvalue,andthosethatmayfailtomatchaspecifiedvalueatruntime.

Thefirstkindofpatternisusedfordestructuringvaluesinsimplevariable,constant,andoptionalbindings.Theseincludewildcardpatterns,identifierpatterns,andanyvaluebindingortuplepatternscontainingthem.Youcanspecifyatypeannotationforthesepatternstoconstrainthemtomatchonlyvaluesofacertaintype.

Thesecondkindofpatternisusedforfullpatternmatching,wherethevaluesyou’retryingtomatchagainstmaynotbethereatruntime.Theseincludeenumerationcasepatterns,optionalpatterns,expressionpatterns,andtype-castingpatterns.Youusethesepatternsinacaselabelofaswitchstatement,acatchclauseofadostatement,orinthecaseconditionofanif,while,guard,orfor-instatement.

GRAMMAR OF A PATTERN

pattern → wildcard-pattern type-annotation optpattern → identifier-pattern type-annotation optpattern → value-binding-patternpattern → tuple-pattern type-annotation optpattern → enum-case-patternpattern → optional-patternpattern → type-casting-patternpattern → expression-pattern

Page 708: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

WildcardPattern

Awildcardpatternmatchesandignoresanyvalueandconsistsofanunderscore(_).Useawildcardpatternwhenyoudon’tcareaboutthevaluesbeingmatchedagainst.Forexample,thefollowingcodeiteratesthroughtheclosedrange1...3,ignoringthecurrentvalueoftherangeoneachiterationoftheloop:

1 for_in1...3{

2 //Dosomethingthreetimes.

3 }

GRAMMAR OF AW I LDCARD PATTERN

wildcard-pattern → _

IdentifierPattern

Anidentifierpatternmatchesanyvalueandbindsthematchedvaluetoavariableorconstantname.Forexample,inthefollowingconstantdeclaration,someValueisanidentifierpatternthatmatchesthevalue42oftypeInt:

letsomeValue=42

Whenthematchsucceeds,thevalue42isbound(assigned)totheconstantnamesomeValue.

Whenthepatternontheleft-handsideofavariableorconstantdeclarationisanidentifierpattern,theidentifierpatternisimplicitlyasubpatternofavalue-bindingpattern.

GRAMMAR OF AN I DENT I F I ER PATTERN

identifier-pattern → identifier

Page 709: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Value-BindingPattern

Avalue-bindingpatternbindsmatchedvaluestovariableorconstantnames.Value-bindingpatternsthatbindamatchedvaluetothenameofaconstantbeginwiththeletkeyword;thosethatbindtothenameofvariablebeginwiththevarkeyword.

Identifierspatternswithinavalue-bindingpatternbindnewnamedvariablesorconstantstotheirmatchingvalues.Forexample,youcandecomposetheelementsofatupleandbindthevalueofeachelementtoacorrespondingidentifierpattern.

1 letpoint=(3,2)

2 switchpoint{

3 //Bindxandytotheelementsofpoint.

4 caselet(x,y):

5 print("Thepointisat(\(x),\(y)).")

6 }

7 //Prints"Thepointisat(3,2)."

Intheexampleabove,letdistributestoeachidentifierpatterninthetuplepattern(x,y).Becauseofthisbehavior,theswitchcasescaselet(x,y):andcase(letx,lety):matchthesamevalues.

GRAMMAR OF A VALUE -B IND ING PATTERN

value-binding-pattern → var pattern | let pattern

TuplePattern

Atuplepatternisacomma-separatedlistofzeroormorepatterns,enclosedinparentheses.Tuplepatternsmatchvaluesofcorrespondingtupletypes.

Youcanconstrainatuplepatterntomatchcertainkindsoftupletypesbyusing

Page 710: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

typeannotations.Forexample,thetuplepattern(x,y):(Int,Int)intheconstantdeclarationlet(x,y):(Int,Int)=(1,2)matchesonlytupletypesinwhichbothelementsareoftypeInt.

Whenatuplepatternisusedasthepatterninafor-instatementorinavariableorconstantdeclaration,itcancontainonlywildcardpatterns,identifierpatterns,optionalpatterns,orothertuplepatternsthatcontainthose.Forexample,thefollowingcodeisn’tvalidbecausetheelement0inthetuplepattern(x,0)isanexpressionpattern:

1 letpoints=[(0,0),(1,0),(1,1),(2,0),(2,1)]

2 //Thiscodeisn'tvalid.

3 for(x,0)inpoints{

4 /*...*/

5 }

Theparenthesesaroundatuplepatternthatcontainsasingleelementhavenoeffect.Thepatternmatchesvaluesofthatsingleelement’stype.Forexample,thefollowingareequivalent:

1 leta=2//a:Int=2

2 let(a)=2//a:Int=2

3 let(a):Int=2//a:Int=2

GRAMMAR OF ATUPLE PATTERN

tuple-pattern → ( tuple-pattern-element-list opt )tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element , tuple-

pattern-element-listtuple-pattern-element → pattern | identifier : pattern

EnumerationCasePattern

Anenumerationcasepatternmatchesacaseofanexistingenumerationtype.

Page 711: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Enumerationcasepatternsappearinswitchstatementcaselabelsandinthecaseconditionsofif,while,guard,andfor-instatements.

Iftheenumerationcaseyou’retryingtomatchhasanyassociatedvalues,thecorrespondingenumerationcasepatternmustspecifyatuplepatternthatcontainsoneelementforeachassociatedvalue.Foranexamplethatusesaswitchstatementtomatchenumerationcasescontainingassociatedvalues,seeAssociatedValues.

Anenumerationcasepatternalsomatchesvaluesofthatcasewrappedinanoptional.Thissimplifiedsyntaxletsyouomitanoptionalpattern.Notethat,becauseOptionalisimplementedasanenumeration,.noneand.somecanappearinthesameswitchasthecasesoftheenumerationtype.

1 enumSomeEnum{caseleft,right}

2 letx:SomeEnum?=.left

3 switchx{

4 case.left:

5 print("Turnleft")

6 case.right:

7 print("Turnright")

8 casenil:

9 print("Keepgoingstraight")

10 }

11 //Prints"Turnleft"

GRAMMAR OF AN ENUMERAT ION CASE PATTERN

enum-case-pattern → type-identifier opt . enum-case-name tuple-pattern opt

OptionalPattern

Anoptionalpatternmatchesvalueswrappedinasome(Wrapped)caseofan

Page 712: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Optional<Wrapped>enumeration.Optionalpatternsconsistofanidentifierpatternfollowedimmediatelybyaquestionmarkandappearinthesameplacesasenumerationcasepatterns.

BecauseoptionalpatternsaresyntacticsugarforOptionalenumerationcasepatterns,thefollowingareequivalent:

1 letsomeOptional:Int?=42

2 //Matchusinganenumerationcasepattern.

3 ifcase.some(letx)=someOptional{

4 print(x)

5 }

6

7 //Matchusinganoptionalpattern.

8 ifcaseletx?=someOptional{

9 print(x)

10 }

Theoptionalpatternprovidesaconvenientwaytoiterateoveranarrayofoptionalvaluesinafor-instatement,executingthebodyofthelooponlyfornon-nilelements.

1 letarrayOfOptionalInts:[Int?]=[nil,2,3,nil,5]

2 //Matchonlynon-nilvalues.

3 forcaseletnumber?inarrayOfOptionalInts{

4 print("Founda\(number)")

5 }

6 //Founda2

7 //Founda3

8 //Founda5

GRAMMAR OF AN OPT IONALPATTERN

optional-pattern → identifier-pattern ?

Page 713: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Type-CastingPatterns

Therearetwotype-castingpatterns,theispatternandtheaspattern.Theispatternappearsonlyinswitchstatementcaselabels.Theisandaspatternshavethefollowingform:

is type

pattern as type

Theispatternmatchesavalueifthetypeofthatvalueatruntimeisthesameasthetypespecifiedintheright-handsideoftheispattern—orasubclassofthattype.Theispatternbehavesliketheisoperatorinthattheybothperformatypecastbutdiscardthereturnedtype.

Theaspatternmatchesavalueifthetypeofthatvalueatruntimeisthesameasthetypespecifiedintheright-handsideoftheaspattern—orasubclassofthattype.Ifthematchsucceeds,thetypeofthematchedvalueiscasttothepatternspecifiedintheright-handsideoftheaspattern.

Foranexamplethatusesaswitchstatementtomatchvalueswithisandaspatterns,seeTypeCastingforAnyandAnyObject.

GRAMMAR OF ATYPE CAST ING PATTERN

type-casting-pattern → is-pattern | as-patternis-pattern → is typeas-pattern → pattern as type

ExpressionPattern

Anexpressionpatternrepresentsthevalueofanexpression.Expressionpatternsappearonlyinswitchstatementcaselabels.

Page 714: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

TheexpressionrepresentedbytheexpressionpatterniscomparedwiththevalueofaninputexpressionusingtheSwiftstandardlibrary~=operator.Thematchessucceedsifthe~=operatorreturnstrue.Bydefault,the~=operatorcomparestwovaluesofthesametypeusingthe==operator.Itcanalsomatchavaluewitharangeofvalues,bycheckingwhetherthevalueiscontainedwithintherange,asthefollowingexampleshows.

1 letpoint=(1,2)

2 switchpoint{

3 case(0,0):

4 print("(0,0)isattheorigin.")

5 case(-2...2,-2...2):

6 print("(\(point.0),\(point.1))isneartheorigin.")

7 default:

8 print("Thepointisat(\(point.0),\(point.1)).")

9 }

10 //Prints"(1,2)isneartheorigin."

Youcanoverloadthe~=operatortoprovidecustomexpressionmatchingbehavior.Forexample,youcanrewritetheaboveexampletocomparethepointexpressionwithastringrepresentationsofpoints.

1 //Overloadthe~=operatortomatchastringwithaninteger.

2 func~=(pattern:String,value:Int)->Bool{

3 returnpattern=="\(value)"

4 }

5 switchpoint{

6 case("0","0"):

7 print("(0,0)isattheorigin.")

8 default:

9 print("Thepointisat(\(point.0),\(point.1)).")

10 }

Page 715: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

11 //Prints"Thepointisat(1,2)."

GRAMMAR OF AN EXPRESS ION PATTERN

expression-pattern → expression

Page 716: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GenericParametersandArguments

Thischapterdescribesparametersandargumentsforgenerictypes,functions,andinitializers.Whenyoudeclareagenerictype,function,subscript,orinitializer,youspecifythetypeparametersthatthegenerictype,function,orinitializercanworkwith.Thesetypeparametersactasplaceholdersthatarereplacedbyactualconcretetypeargumentswhenaninstanceofagenerictypeiscreatedoragenericfunctionorinitializeriscalled.

ForanoverviewofgenericsinSwift,seeGenerics.

GenericParameterClause

Agenericparameterclausespecifiesthetypeparametersofagenerictypeorfunction,alongwithanyassociatedconstraintsandrequirementsonthoseparameters.Agenericparameterclauseisenclosedinanglebrackets(<>)andhasthefollowingform:

< genericparameterlist >

Thegenericparameterlistisacomma-separatedlistofgenericparameters,eachofwhichhasthefollowingform:

typeparameter : constraint

Agenericparameterconsistsofatypeparameterfollowedbyanoptionalconstraint.Atypeparameterissimplythenameofaplaceholdertype(forexample,T,U,V,Key,Value,andsoon).Youhaveaccesstothetypeparameters(andanyoftheirassociatedtypes)intherestofthetype,function,orinitializerdeclaration,includinginthesignatureofthefunctionorinitializer.

Theconstraintspecifiesthatatypeparameterinheritsfromaspecificclassorconformstoaprotocolorprotocolcomposition.Forexample,inthegeneric

Page 717: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

functionbelow,thegenericparameterT:ComparableindicatesthatanytypeargumentsubstitutedforthetypeparameterTmustconformtotheComparableprotocol.

1 funcsimpleMax<T:Comparable>(_x:T,_y:T)->T{

2 ifx<y{

3 returny

4 }

5 returnx

6 }

BecauseIntandDouble,forexample,bothconformtotheComparableprotocol,thisfunctionacceptsargumentsofeithertype.Incontrastwithgenerictypes,youdon’tspecifyagenericargumentclausewhenyouuseagenericfunctionorinitializer.Thetypeargumentsareinsteadinferredfromthetypeoftheargumentspassedtothefunctionorinitializer.

1 simpleMax(17,42)//TisinferredtobeInt

2 simpleMax(3.14159,2.71828)//TisinferredtobeDouble

GenericWhereClausesYoucanspecifyadditionalrequirementsontypeparametersandtheirassociatedtypesbyincludingagenericwhereclauserightbeforetheopeningcurlybraceofatypeorfunction’sbody.Agenericwhereclauseconsistsofthewherekeyword,followedbyacomma-separatedlistofoneormorerequirements.

where requirements

Therequirementsinagenericwhereclausespecifythatatypeparameterinheritsfromaclassorconformstoaprotocolorprotocolcomposition.Althoughthegenericwhereclauseprovidessyntacticsugarforexpressingsimpleconstraintsontypeparameters(forexample,<T:Comparable>isequivalentto<T>whereT:Comparableandsoon),youcanuseittoprovidemorecomplexconstraintson

Page 718: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

typeparametersandtheirassociatedtypes.Forexample,youcanconstraintheassociatedtypesoftypeparameterstoconformtoprotocols.Forexample,<S:Sequence>whereS.Iterator.Element:EquatablespecifiesthatSconformstotheSequenceprotocolandthattheassociatedtypeS.Iterator.ElementconformstotheEquatableprotocol.Thisconstraintensuresthateachelementofthesequenceisequatable.

Youcanalsospecifytherequirementthattwotypesbeidentical,usingthe==operator.Forexample,<S1:Sequence,S2:Sequence>whereS1.Iterator.Element==S2.Iterator.ElementexpressestheconstraintsthatS1andS2conformtotheSequenceprotocolandthattheelementsofbothsequencesmustbeofthesametype.

Anytypeargumentsubstitutedforatypeparametermustmeetalltheconstraintsandrequirementsplacedonthetypeparameter.

Youcanoverloadagenericfunctionorinitializerbyprovidingdifferentconstraints,requirements,orbothonthetypeparameters.Whenyoucallanoverloadedgenericfunctionorinitializer,thecompilerusestheseconstraintstoresolvewhichoverloadedfunctionorinitializertoinvoke.

Formoreinformationaboutgenericwhereclausesandtoseeanexampleofoneinagenericfunctiondeclaration,seeGenericWhereClauses.

GRAMMAR OF AGENER IC PARAMETER CLAUSE

generic-parameter-clause → < generic-parameter-list >generic-parameter-list → generic-parameter | generic-parameter , generic-parameter-

listgeneric-parameter → type-namegeneric-parameter → type-name : type-identifiergeneric-parameter → type-name : protocol-composition-typegeneric-where-clause → where requirement-listrequirement-list → requirement | requirement , requirement-listrequirement → conformance-requirement | same-type-requirementconformance-requirement → type-identifier : type-identifierconformance-requirement → type-identifier : protocol-composition-typesame-type-requirement → type-identifier == type

Page 719: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GenericArgumentClause

Agenericargumentclausespecifiesthetypeargumentsofagenerictype.Agenericargumentclauseisenclosedinanglebrackets(<>)andhasthefollowingform:

< genericargumentlist >

Thegenericargumentlistisacomma-separatedlistoftypearguments.Atypeargumentisthenameofanactualconcretetypethatreplacesacorrespondingtypeparameterinthegenericparameterclauseofagenerictype.Theresultisaspecializedversionofthatgenerictype.TheexamplebelowshowsasimplifiedversionoftheSwiftstandardlibrary’sgenericdictionarytype.

1 structDictionary<Key:Hashable,Value>:Collection,

ExpressibleByDictionaryLiteral{

2 /*...*/

3 }

ThespecializedversionofthegenericDictionarytype,Dictionary<String,Int>isformedbyreplacingthegenericparametersKey:HashableandValuewiththeconcretetypeargumentsStringandInt.Eachtypeargumentmustsatisfyalltheconstraintsofthegenericparameteritreplaces,includinganyadditionalrequirementsspecifiedinagenericwhereclause.Intheexampleabove,theKeytypeparameterisconstrainedtoconformtotheHashableprotocolandthereforeStringmustalsoconformtotheHashableprotocol.

Youcanalsoreplaceatypeparameterwithatypeargumentthatisitselfaspecializedversionofagenerictype(provideditsatisfiestheappropriateconstraintsandrequirements).Forexample,youcanreplacethetypeparameterElementinArray<Element>withaspecializedversionofanarray,Array<Int>,toformanarraywhoseelementsarethemselvesarraysofintegers.

letarrayOfArrays:Array<Array<Int>>=[[1,2,3],[4,5,6],

[7,8,9]]

Page 720: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AsmentionedinGenericParameterClause,youdon’tuseagenericargumentclausetospecifythetypeargumentsofagenericfunctionorinitializer.

GRAMMAR OF AGENER IC ARGUMENT CLAUSE

generic-argument-clause → < generic-argument-list >generic-argument-list → generic-argument | generic-argument , generic-argument-listgeneric-argument → type

Page 721: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

SummaryoftheGrammar

LexicalStructure

GRAMMAR OF WH I TESPACE

whitespace → whitespace-item whitespace optwhitespace-item → line-breakwhitespace-item → commentwhitespace-item → multiline-commentwhitespace-item → U+0000,U+0009,U+000B,U+000C,orU+0020line-break → U+000Aline-break → U+000Dline-break → U+000DfollowedbyU+000Acomment → // comment-text line-breakmultiline-comment → /* multiline-comment-text */comment-text → comment-text-item comment-text optcomment-text-item → AnyUnicodescalarvalueexceptU+000AorU+000Dmultiline-comment-text → multiline-comment-text-item multiline-comment-text optmultiline-comment-text-item → multiline-commentmultiline-comment-text-item → comment-text-itemmultiline-comment-text-item → AnyUnicodescalarvalueexcept /* or */

GRAMMAR OF AN I DENT I F I ER

identifier → identifier-head identifier-characters optidentifier → ` identifier-head identifier-characters opt `identifier → implicit-parameter-nameidentifier → property-wrapper-projectionidentifier-list → identifier | identifier , identifier-listidentifier-head → Upper-orlowercaseletterAthroughZidentifier-head → _identifier-head → U+00A8,U+00AA,U+00AD,U+00AF,U+00B2–U+00B5,orU+00B7–

U+00BAidentifier-head → U+00BC–U+00BE,U+00C0–U+00D6,U+00D8–U+00F6,orU+00F8–

U+00FFidentifier-head → U+0100–U+02FF,U+0370–U+167F,U+1681–U+180D,orU+180F–

U+1DBFidentifier-head → U+1E00–U+1FFFidentifier-head → U+200B–U+200D,U+202A–U+202E,U+203F–U+2040,U+2054,or

U+2060–U+206Fidentifier-head → U+2070–U+20CF,U+2100–U+218F,U+2460–U+24FF,orU+2776–

Page 722: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

U+2793identifier-head → U+2C00–U+2DFForU+2E80–U+2FFFidentifier-head → U+3004–U+3007,U+3021–U+302F,U+3031–U+303F,orU+3040–

U+D7FFidentifier-head → U+F900–U+FD3D,U+FD40–U+FDCF,U+FDF0–U+FE1F,orU+FE30–

U+FE44identifier-head → U+FE47–U+FFFDidentifier-head → U+10000–U+1FFFD,U+20000–U+2FFFD,U+30000–U+3FFFD,or

U+40000–U+4FFFDidentifier-head → U+50000–U+5FFFD,U+60000–U+6FFFD,U+70000–U+7FFFD,or

U+80000–U+8FFFDidentifier-head → U+90000–U+9FFFD,U+A0000–U+AFFFD,U+B0000–U+BFFFD,or

U+C0000–U+CFFFDidentifier-head → U+D0000–U+DFFFDorU+E0000–U+EFFFDidentifier-character → Digit0through9identifier-character → U+0300–U+036F,U+1DC0–U+1DFF,U+20D0–U+20FF,or

U+FE20–U+FE2Fidentifier-character → identifier-headidentifier-characters → identifier-character identifier-characters optimplicit-parameter-name → $ decimal-digitsproperty-wrapper-projection → $ identifier-characters

GRAMMAR OF A L I TERAL

literal → numeric-literal | string-literal | boolean-literal | nil-literalnumeric-literal → -opt integer-literal | -opt floating-point-literalboolean-literal → true | falsenil-literal → nil

GRAMMAR OF AN I NTEGER L I TERAL

integer-literal → binary-literalinteger-literal → octal-literalinteger-literal → decimal-literalinteger-literal → hexadecimal-literalbinary-literal → 0b binary-digit binary-literal-characters optbinary-digit → Digit0or1binary-literal-character → binary-digit | _binary-literal-characters → binary-literal-character binary-literal-characters optoctal-literal → 0o octal-digit octal-literal-characters optoctal-digit → Digit0through7octal-literal-character → octal-digit | _octal-literal-characters → octal-literal-character octal-literal-characters optdecimal-literal → decimal-digit decimal-literal-characters optdecimal-digit → Digit0through9decimal-digits → decimal-digit decimal-digits optdecimal-literal-character → decimal-digit | _

Page 723: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

decimal-literal-characters → decimal-literal-character decimal-literal-characters opthexadecimal-literal → 0x hexadecimal-digit hexadecimal-literal-characters opthexadecimal-digit → Digit0through9,athroughf,orAthroughFhexadecimal-literal-character → hexadecimal-digit | _hexadecimal-literal-characters → hexadecimal-literal-character hexadecimal-literal-

characters opt

GRAMMAR OF A F LOAT ING -PO INT L I TERAL

floating-point-literal → decimal-literal decimal-fraction opt decimal-exponent optfloating-point-literal → hexadecimal-literal hexadecimal-fraction opt hexadecimal-

exponentdecimal-fraction → . decimal-literaldecimal-exponent → floating-point-e sign opt decimal-literalhexadecimal-fraction → . hexadecimal-digit hexadecimal-literal-characters opthexadecimal-exponent → floating-point-p sign opt decimal-literalfloating-point-e → e | Efloating-point-p → p | Psign → + | -

GRAMMAR OF A STR ING L I TERAL

string-literal → static-string-literal | interpolated-string-literalstring-literal-opening-delimiter → extended-string-literal-delimiter opt "string-literal-closing-delimiter → " extended-string-literal-delimiter optstatic-string-literal → string-literal-opening-delimiter quoted-text opt string-literal-closing-

delimiterstatic-string-literal → multiline-string-literal-opening-delimiter multiline-quoted-text opt

multiline-string-literal-closing-delimitermultiline-string-literal-opening-delimiter → extended-string-literal-delimiter """multiline-string-literal-closing-delimiter → """ extended-string-literal-delimiterextended-string-literal-delimiter → # extended-string-literal-delimiter optquoted-text → quoted-text-item quoted-text optquoted-text-item → escaped-characterquoted-text-item → AnyUnicodescalarvalueexcept " , \ ,U+000A,orU+000Dmultiline-quoted-text → multiline-quoted-text-item multiline-quoted-text optmultiline-quoted-text-item → escaped-charactermultiline-quoted-text-item → AnyUnicodescalarvalueexcept \multiline-quoted-text-item → escaped-newlineinterpolated-string-literal → string-literal-opening-delimiter interpolated-text opt string-

literal-closing-delimiterinterpolated-string-literal → multiline-string-literal-opening-delimiter interpolated-text opt

multiline-string-literal-closing-delimiterinterpolated-text → interpolated-text-item interpolated-text optinterpolated-text-item → \( expression ) | quoted-text-item

Page 724: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

multiline-interpolated-text → multiline-interpolated-text-item multiline-interpolated-text optmultiline-interpolated-text-item → \( expression ) |multiline-quoted-text-itemescape-sequence → \ extended-string-literal-delimiterescaped-character → escape-sequence 0 | escape-sequence \ | escape-sequence t |

escape-sequence n | escape-sequence r | escape-sequence " | escape-sequence'

escaped-character → escape-sequence u { unicode-scalar-digits }unicode-scalar-digits → Betweenoneandeighthexadecimaldigitsescaped-newline → escape-sequence whitespace opt line-break

GRAMMAR OF OPERATORS

operator → operator-head operator-characters optoperator → dot-operator-head dot-operator-charactersoperator-head → / | = | - | + | ! | * | % | < | > | & | | | ^ | ~ | ?operator-head → U+00A1–U+00A7operator-head → U+00A9orU+00ABoperator-head → U+00ACorU+00AEoperator-head → U+00B0–U+00B1operator-head → U+00B6,U+00BB,U+00BF,U+00D7,orU+00F7operator-head → U+2016–U+2017operator-head → U+2020–U+2027operator-head → U+2030–U+203Eoperator-head → U+2041–U+2053operator-head → U+2055–U+205Eoperator-head → U+2190–U+23FFoperator-head → U+2500–U+2775operator-head → U+2794–U+2BFFoperator-head → U+2E00–U+2E7Foperator-head → U+3001–U+3003operator-head → U+3008–U+3020operator-head → U+3030operator-character → operator-headoperator-character → U+0300–U+036Foperator-character → U+1DC0–U+1DFFoperator-character → U+20D0–U+20FFoperator-character → U+FE00–U+FE0Foperator-character → U+FE20–U+FE2Foperator-character → U+E0100–U+E01EFoperator-characters → operator-character operator-characters optdot-operator-head → .dot-operator-character → . | operator-characterdot-operator-characters → dot-operator-character dot-operator-characters optbinary-operator → operatorprefix-operator → operatorpostfix-operator → operator

Page 725: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Types

GRAMMAR OF ATYPE

type → function-typetype → array-typetype → dictionary-typetype → type-identifiertype → tuple-typetype → optional-typetype → implicitly-unwrapped-optional-typetype → protocol-composition-typetype → opaque-typetype → metatype-typetype → self-typetype → Anytype → ( type )

GRAMMAR OF ATYPE ANNOTAT ION

type-annotation → : attributes opt inoutopt type

GRAMMAR OF ATYPE I DENT I F I ER

type-identifier → type-name generic-argument-clause opt | type-name generic-argument-clause opt . type-identifier

type-name → identifier

GRAMMAR OF ATUPLE TYPE

tuple-type → ( ) | ( tuple-type-element , tuple-type-element-list )tuple-type-element-list → tuple-type-element | tuple-type-element , tuple-type-element-

listtuple-type-element → element-name type-annotation | typeelement-name → identifier

GRAMMAR OF A FUNCT ION TYPE

function-type → attributes opt function-type-argument-clause throwsopt -> typefunction-type-argument-clause → ( )function-type-argument-clause → ( function-type-argument-list ...opt )function-type-argument-list → function-type-argument | function-type-argument ,

function-type-argument-listfunction-type-argument → attributes opt inoutopt type | argument-label type-

annotationargument-label → identifier

Page 726: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF AN ARRAY TYPE

array-type → [ type ]

GRAMMAR OF AD ICT IONARY TYPE

dictionary-type → [ type : type ]

GRAMMAR OF AN OPT IONALTYPE

optional-type → type ?

GRAMMAR OF AN IMPL IC I T LY UNWRAPPED OPT IONALTYPE

implicitly-unwrapped-optional-type → type !

GRAMMAR OF A PROTOCOLCOMPOS I T ION TYPE

protocol-composition-type → type-identifier & protocol-composition-continuationprotocol-composition-continuation → type-identifier | protocol-composition-type

GRAMMAR OF AN OPAQUE TYPE

opaque-type → some type

GRAMMAR OF AMETATYPE TYPE

metatype-type → type . Type | type . Protocol

GRAMMAR OF A SELF TYPE

self-type → Self

GRAMMAR OF ATYPE I NHER I TANCE CLAUSE

type-inheritance-clause → : type-inheritance-listtype-inheritance-list → type-identifier | type-identifier , type-inheritance-list

Expressions

GRAMMAR OF AN EXPRESS ION

expression → try-operator opt prefix-expression binary-expressions optexpression-list → expression | expression , expression-list

Page 727: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF A PREF IX EXPRESS ION

prefix-expression → prefix-operator opt postfix-expressionprefix-expression → in-out-expressionin-out-expression → & identifier

GRAMMAR OF ATRY EXPRESS ION

try-operator → try | try ? | try !

GRAMMAR OF A B INARY EXPRESS ION

binary-expression → binary-operator prefix-expressionbinary-expression → assignment-operator try-operator opt prefix-expressionbinary-expression → conditional-operator try-operator opt prefix-expressionbinary-expression → type-casting-operatorbinary-expressions → binary-expression binary-expressions opt

GRAMMAR OF AN ASS IGNMENT OPERATOR

assignment-operator → =

GRAMMAR OF ACOND I T IONALOPERATOR

conditional-operator → ? expression :

GRAMMAR OF ATYPE -CAST ING OPERATOR

type-casting-operator → is typetype-casting-operator → as typetype-casting-operator → as ? typetype-casting-operator → as ! type

GRAMMAR OF A PR IMARY EXPRESS ION

primary-expression → identifier generic-argument-clause optprimary-expression → literal-expressionprimary-expression → self-expressionprimary-expression → superclass-expressionprimary-expression → closure-expressionprimary-expression → parenthesized-expressionprimary-expression → tuple-expressionprimary-expression → implicit-member-expressionprimary-expression → wildcard-expressionprimary-expression → key-path-expressionprimary-expression → selector-expressionprimary-expression → key-path-string-expression

Page 728: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF A L I TERALEXPRESS ION

literal-expression → literalliteral-expression → array-literal | dictionary-literal | playground-literalliteral-expression → #file | #line | #column | #function | #dsohandlearray-literal → [ array-literal-items opt ]array-literal-items → array-literal-item ,opt | array-literal-item , array-literal-itemsarray-literal-item → expressiondictionary-literal → [ dictionary-literal-items ] | [ : ]dictionary-literal-items → dictionary-literal-item ,opt | dictionary-literal-item , dictionary-

literal-itemsdictionary-literal-item → expression : expressionplayground-literal → #colorLiteral ( red : expression , green : expression

, blue : expression , alpha : expression )playground-literal → #fileLiteral ( resourceName : expression )playground-literal → #imageLiteral ( resourceName : expression )

GRAMMAR OF A SELF EXPRESS ION

self-expression → self | self-method-expression | self-subscript-expression | self-initializer-expression

self-method-expression → self . identifierself-subscript-expression → self [ function-call-argument-list ]self-initializer-expression → self . init

GRAMMAR OF A SUPERCLASS EXPRESS ION

superclass-expression → superclass-method-expression | superclass-subscript-expression | superclass-initializer-expression

superclass-method-expression → super . identifiersuperclass-subscript-expression → super [ function-call-argument-list ]superclass-initializer-expression → super . init

GRAMMAR OF ACLOSURE EXPRESS ION

closure-expression → { closure-signature opt statements opt }closure-signature → capture-list opt closure-parameter-clause throwsopt function-

result opt inclosure-signature → capture-list inclosure-parameter-clause → ( ) | ( closure-parameter-list ) | identifier-listclosure-parameter-list → closure-parameter | closure-parameter , closure-parameter-

listclosure-parameter → closure-parameter-name type-annotation optclosure-parameter → closure-parameter-name type-annotation ...closure-parameter-name → identifiercapture-list → [ capture-list-items ]capture-list-items → capture-list-item | capture-list-item , capture-list-items

Page 729: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

capture-list-item → capture-specifier opt expressioncapture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

GRAMMAR OF A IMPL IC I T MEMBER EXPRESS ION

implicit-member-expression → . identifier

GRAMMAR OF A PARENTHES I ZED EXPRESS ION

parenthesized-expression → ( expression )

GRAMMAR OF ATUPLE EXPRESS ION

tuple-expression → ( ) | ( tuple-element , tuple-element-list )tuple-element-list → tuple-element | tuple-element , tuple-element-listtuple-element → expression | identifier : expression

GRAMMAR OF AW I LDCARD EXPRESS ION

wildcard-expression → _

GRAMMAR OF A KEY-PATH EXPRESS ION

key-path-expression → \ type opt . key-path-componentskey-path-components → key-path-component | key-path-component . key-path-

componentskey-path-component → identifier key-path-postfixes opt | key-path-postfixeskey-path-postfixes → key-path-postfix key-path-postfixes optkey-path-postfix → ? | ! | self | [ function-call-argument-list ]

GRAMMAR OF A SELECTOR EXPRESS ION

selector-expression → #selector ( expression )selector-expression → #selector ( getter: expression )selector-expression → #selector ( setter: expression )

GRAMMAR OF A KEY-PATH STR ING EXPRESS ION

key-path-string-expression → #keyPath ( expression )

GRAMMAR OF A POSTF IX EXPRESS ION

postfix-expression → primary-expressionpostfix-expression → postfix-expression postfix-operatorpostfix-expression → function-call-expressionpostfix-expression → initializer-expressionpostfix-expression → explicit-member-expression

Page 730: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

postfix-expression → postfix-self-expressionpostfix-expression → subscript-expressionpostfix-expression → forced-value-expressionpostfix-expression → optional-chaining-expression

GRAMMAR OF A FUNCT ION CALL EXPRESS ION

function-call-expression → postfix-expression function-call-argument-clausefunction-call-expression → postfix-expression function-call-argument-clause opt trailing-

closurefunction-call-argument-clause → ( ) | ( function-call-argument-list )function-call-argument-list → function-call-argument | function-call-argument , function-

call-argument-listfunction-call-argument → expression | identifier : expressionfunction-call-argument → operator | identifier : operatortrailing-closure → closure-expression

GRAMMAR OF AN I N I T I A L I ZER EXPRESS ION

initializer-expression → postfix-expression . initinitializer-expression → postfix-expression . init ( argument-names )

GRAMMAR OF AN EXPL IC I T MEMBER EXPRESS ION

explicit-member-expression → postfix-expression . decimal-digitsexplicit-member-expression → postfix-expression . identifier generic-argument-clause

optexplicit-member-expression → postfix-expression . identifier ( argument-names )argument-names → argument-name argument-names optargument-name → identifier :

GRAMMAR OF A POSTF IX SELF EXPRESS ION

postfix-self-expression → postfix-expression . self

GRAMMAR OF A SUBSCR IPT EXPRESS ION

subscript-expression → postfix-expression [ function-call-argument-list ]

GRAMMAR OF A FORCED -VALUE EXPRESS ION

forced-value-expression → postfix-expression !

GRAMMAR OF AN OPT IONAL -CHA IN ING EXPRESS ION

optional-chaining-expression → postfix-expression ?

Page 731: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Statements

GRAMMAR OF A STATEMENT

statement → expression ;optstatement → declaration ;optstatement → loop-statement ;optstatement → branch-statement ;optstatement → labeled-statement ;optstatement → control-transfer-statement ;optstatement → defer-statement ;optstatement → do-statement ;optstatement → compiler-control-statementstatements → statement statements opt

GRAMMAR OF A LOOP STATEMENT

loop-statement → for-in-statementloop-statement → while-statementloop-statement → repeat-while-statement

GRAMMAR OF A FOR - IN STATEMENT

for-in-statement → for caseopt pattern in expression where-clause opt code-block

GRAMMAR OF AWH I LE STATEMENT

while-statement → while condition-list code-blockcondition-list → condition | condition , condition-listcondition → expression | availability-condition | case-condition | optional-binding-

conditioncase-condition → case pattern initializeroptional-binding-condition → let pattern initializer | var pattern initializer

GRAMMAR OF AREPEAT-WH I LE STATEMENT

repeat-while-statement → repeat code-block while expression

GRAMMAR OF A BRANCH STATEMENT

branch-statement → if-statementbranch-statement → guard-statementbranch-statement → switch-statement

GRAMMAR OF AN I F STATEMENT

Page 732: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

if-statement → if condition-list code-block else-clause optelse-clause → else code-block | else if-statement

GRAMMAR OF AGUARD STATEMENT

guard-statement → guard condition-list else code-block

GRAMMAR OF A SW ITCH STATEMENT

switch-statement → switch expression { switch-cases opt }switch-cases → switch-case switch-cases optswitch-case → case-label statementsswitch-case → default-label statementsswitch-case → conditional-switch-casecase-label → attributes opt case case-item-list :case-item-list → pattern where-clause opt | pattern where-clause opt , case-item-listdefault-label → attributes opt default :where-clause → where where-expressionwhere-expression → expressionconditional-switch-case → switch-if-directive-clause switch-elseif-directive-clauses opt

switch-else-directive-clause opt endif-directiveswitch-if-directive-clause → if-directive compilation-condition switch-cases optswitch-elseif-directive-clauses → elseif-directive-clause switch-elseif-directive-clauses optswitch-elseif-directive-clause → elseif-directive compilation-condition switch-cases optswitch-else-directive-clause → else-directive switch-cases opt

GRAMMAR OF A LABELED STATEMENT

labeled-statement → statement-label loop-statementlabeled-statement → statement-label if-statementlabeled-statement → statement-label switch-statementlabeled-statement → statement-label do-statementstatement-label → label-name :label-name → identifier

GRAMMAR OF ACONTROLTRANSFER STATEMENT

control-transfer-statement → break-statementcontrol-transfer-statement → continue-statementcontrol-transfer-statement → fallthrough-statementcontrol-transfer-statement → return-statementcontrol-transfer-statement → throw-statement

GRAMMAR OF A BREAK STATEMENT

break-statement → break label-name opt

Page 733: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF ACONT INUE STATEMENT

continue-statement → continue label-name opt

GRAMMAR OF A FALLTHROUGH STATEMENT

fallthrough-statement → fallthrough

GRAMMAR OF ARETURN STATEMENT

return-statement → return expression opt

GRAMMAR OF ATHROWSTATEMENT

throw-statement → throw expression

GRAMMAR OF ADEFER STATEMENT

defer-statement → defer code-block

GRAMMAR OF ADO STATEMENT

do-statement → do code-block catch-clauses optcatch-clauses → catch-clause catch-clauses optcatch-clause → catch pattern opt where-clause opt code-block

GRAMMAR OF ACOMP I LER CONTROLSTATEMENT

compiler-control-statement → conditional-compilation-blockcompiler-control-statement → line-control-statementcompiler-control-statement → diagnostic-statement

GRAMMAR OF ACOND I T IONALCOMP I LAT ION BLOCK

conditional-compilation-block → if-directive-clause elseif-directive-clauses opt else-directive-clause opt endif-directive

if-directive-clause → if-directive compilation-condition statements optelseif-directive-clauses → elseif-directive-clause elseif-directive-clauses optelseif-directive-clause → elseif-directive compilation-condition statements optelse-directive-clause → else-directive statements optif-directive → #ifelseif-directive → #elseifelse-directive → #elseendif-directive → #endifcompilation-condition → platform-condition

Page 734: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

compilation-condition → identifiercompilation-condition → boolean-literalcompilation-condition → ( compilation-condition )compilation-condition → ! compilation-conditioncompilation-condition → compilation-condition && compilation-conditioncompilation-condition → compilation-condition || compilation-conditionplatform-condition → os ( operating-system )platform-condition → arch ( architecture )platform-condition → swift ( >= swift-version ) | swift ( < swift-version )platform-condition → compiler ( >= swift-version ) | compiler ( < swift-version

)

platform-condition → canImport ( module-name )platform-condition → targetEnvironment ( environment )operating-system → macOS | iOS | watchOS | tvOSarchitecture → i386 | x86_64 | arm | arm64swift-version → decimal-digits swift-version-continuation optswift-version-continuation → . decimal-digits swift-version-continuation optmodule-name → identifierenvironment → simulator

GRAMMAR OF A L I NE CONTROLSTATEMENT

line-control-statement → #sourceLocation ( file: file-name , line: line-number )

line-control-statement → #sourceLocation ( )line-number → Adecimalintegergreaterthanzerofile-name → static-string-literal

GRAMMAR OF ACOMP I LE - T IME D I AGNOST IC STATEMENT

diagnostic-statement → #error ( diagnostic-message )diagnostic-statement → #warning ( diagnostic-message )diagnostic-message → static-string-literal

GRAMMAR OF AN AVA I LAB I L I TY COND I T ION

availability-condition → #available ( availability-arguments )availability-arguments → availability-argument | availability-argument , availability-

argumentsavailability-argument → platform-name platform-versionavailability-argument → *platform-name → iOS | iOSApplicationExtensionplatform-name → macOS | macOSApplicationExtensionplatform-name → watchOSplatform-name → tvOSplatform-version → decimal-digitsplatform-version → decimal-digits . decimal-digits

Page 735: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

platform-version → decimal-digits . decimal-digits . decimal-digits

Declarations

GRAMMAR OF ADECLARAT ION

declaration → import-declarationdeclaration → constant-declarationdeclaration → variable-declarationdeclaration → typealias-declarationdeclaration → function-declarationdeclaration → enum-declarationdeclaration → struct-declarationdeclaration → class-declarationdeclaration → protocol-declarationdeclaration → initializer-declarationdeclaration → deinitializer-declarationdeclaration → extension-declarationdeclaration → subscript-declarationdeclaration → operator-declarationdeclaration → precedence-group-declarationdeclarations → declaration declarations opt

GRAMMAR OF ATOP - LEVELDECLARAT ION

top-level-declaration → statements opt

GRAMMAR OF ACODE BLOCK

code-block → { statements opt }

GRAMMAR OF AN IMPORT DECLARAT ION

import-declaration → attributes opt import import-kind opt import-pathimport-kind → typealias | struct | class | enum | protocol | let | var |

func

import-path → import-path-identifier | import-path-identifier . import-pathimport-path-identifier → identifier | operator

GRAMMAR OF ACONSTANT DECLARAT ION

constant-declaration → attributes opt declaration-modifiers opt let pattern-initializer-list

pattern-initializer-list → pattern-initializer | pattern-initializer , pattern-initializer-list

Page 736: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

pattern-initializer → pattern initializer optinitializer → = expression

GRAMMAR OF A VAR IABLE DECLARAT ION

variable-declaration → variable-declaration-head pattern-initializer-listvariable-declaration → variable-declaration-head variable-name type-annotation code-

blockvariable-declaration → variable-declaration-head variable-name type-annotation getter-

setter-blockvariable-declaration → variable-declaration-head variable-name type-annotation getter-

setter-keyword-blockvariable-declaration → variable-declaration-head variable-name initializer willSet-didSet-

blockvariable-declaration → variable-declaration-head variable-name type-annotation

initializer opt willSet-didSet-blockvariable-declaration-head → attributes opt declaration-modifiers opt varvariable-name → identifiergetter-setter-block → code-blockgetter-setter-block → { getter-clause setter-clause opt }getter-setter-block → { setter-clause getter-clause }getter-clause → attributes opt mutation-modifier opt get code-blocksetter-clause → attributes opt mutation-modifier opt set setter-name opt code-blocksetter-name → ( identifier )getter-setter-keyword-block → { getter-keyword-clause setter-keyword-clause opt }getter-setter-keyword-block → { setter-keyword-clause getter-keyword-clause }getter-keyword-clause → attributes opt mutation-modifier opt getsetter-keyword-clause → attributes opt mutation-modifier opt setwillSet-didSet-block → { willSet-clause didSet-clause opt }willSet-didSet-block → { didSet-clause willSet-clause opt }willSet-clause → attributes opt willSet setter-name opt code-blockdidSet-clause → attributes opt didSet setter-name opt code-block

GRAMMAR OF ATYPE AL I AS DECLARAT ION

typealias-declaration → attributes opt access-level-modifier opt typealias typealias-name generic-parameter-clause opt typealias-assignment

typealias-name → identifiertypealias-assignment → = type

GRAMMAR OF A FUNCT ION DECLARAT ION

function-declaration → function-head function-name generic-parameter-clause optfunction-signature generic-where-clause opt function-body opt

function-head → attributes opt declaration-modifiers opt func

Page 737: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

function-name → identifier | operatorfunction-signature → parameter-clause throwsopt function-result optfunction-signature → parameter-clause rethrows function-result optfunction-result → -> attributes opt typefunction-body → code-blockparameter-clause → ( ) | ( parameter-list )parameter-list → parameter | parameter , parameter-listparameter → external-parameter-name opt local-parameter-name type-annotation

default-argument-clause optparameter → external-parameter-name opt local-parameter-name type-annotationparameter → external-parameter-name opt local-parameter-name type-annotation ...external-parameter-name → identifierlocal-parameter-name → identifierdefault-argument-clause → = expression

GRAMMAR OF AN ENUMERAT ION DECLARAT ION

enum-declaration → attributes opt access-level-modifier opt union-style-enumenum-declaration → attributes opt access-level-modifier opt raw-value-style-enumunion-style-enum → indirectopt enum enum-name generic-parameter-clause opt

type-inheritance-clause opt generic-where-clause opt { union-style-enum-members

opt }union-style-enum-members → union-style-enum-member union-style-enum-members optunion-style-enum-member → declaration | union-style-enum-case-clause | compiler-

control-statementunion-style-enum-case-clause → attributes opt indirectopt case union-style-enum-

case-listunion-style-enum-case-list → union-style-enum-case | union-style-enum-case , union-

style-enum-case-listunion-style-enum-case → enum-case-name tuple-type optenum-name → identifierenum-case-name → identifierraw-value-style-enum → enum enum-name generic-parameter-clause opt type-

inheritance-clause generic-where-clause opt { raw-value-style-enum-members }raw-value-style-enum-members → raw-value-style-enum-member raw-value-style-enum-

members optraw-value-style-enum-member → declaration | raw-value-style-enum-case-clause |

compiler-control-statementraw-value-style-enum-case-clause → attributes opt case raw-value-style-enum-case-

listraw-value-style-enum-case-list → raw-value-style-enum-case | raw-value-style-enum-

case , raw-value-style-enum-case-listraw-value-style-enum-case → enum-case-name raw-value-assignment optraw-value-assignment → = raw-value-literalraw-value-literal → numeric-literal | static-string-literal | boolean-literal

Page 738: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF A STRUCTURE DECLARAT ION

struct-declaration → attributes opt access-level-modifier opt struct struct-namegeneric-parameter-clause opt type-inheritance-clause opt generic-where-clause optstruct-body

struct-name → identifierstruct-body → { struct-members opt }struct-members → struct-member struct-members optstruct-member → declaration | compiler-control-statement

GRAMMAR OF ACLASS DECLARAT ION

class-declaration → attributes opt access-level-modifier opt finalopt class class-name generic-parameter-clause opt type-inheritance-clause opt generic-where-clause

opt class-bodyclass-declaration → attributes opt final access-level-modifier opt class class-

name generic-parameter-clause opt type-inheritance-clause opt generic-where-clause

opt class-bodyclass-name → identifierclass-body → { class-members opt }class-members → class-member class-members optclass-member → declaration | compiler-control-statement

GRAMMAR OF A PROTOCOLDECLARAT ION

protocol-declaration → attributes opt access-level-modifier opt protocol protocol-name type-inheritance-clause opt generic-where-clause opt protocol-body

protocol-name → identifierprotocol-body → { protocol-members opt }protocol-members → protocol-member protocol-members optprotocol-member → protocol-member-declaration | compiler-control-statementprotocol-member-declaration → protocol-property-declarationprotocol-member-declaration → protocol-method-declarationprotocol-member-declaration → protocol-initializer-declarationprotocol-member-declaration → protocol-subscript-declarationprotocol-member-declaration → protocol-associated-type-declarationprotocol-member-declaration → typealias-declaration

GRAMMAR OF A PROTOCOLPROPERTY DECLARAT ION

protocol-property-declaration → variable-declaration-head variable-name type-annotationgetter-setter-keyword-block

GRAMMAR OF A PROTOCOLMETHOD DECLARAT ION

Page 739: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

protocol-method-declaration → function-head function-name generic-parameter-clauseopt function-signature generic-where-clause opt

GRAMMAR OF A PROTOCOL I N I T I A L I ZER DECLARAT ION

protocol-initializer-declaration → initializer-head generic-parameter-clause optparameter-clause throwsopt generic-where-clause opt

protocol-initializer-declaration → initializer-head generic-parameter-clause optparameter-clause rethrows generic-where-clause opt

GRAMMAR OF A PROTOCOLSUBSCR IPT DECLARAT ION

protocol-subscript-declaration → subscript-head subscript-result generic-where-clauseopt getter-setter-keyword-block

GRAMMAR OF A PROTOCOLASSOC IATED TYPE DECLARAT ION

protocol-associated-type-declaration → attributes opt access-level-modifier optassociatedtype typealias-name type-inheritance-clause opt typealias-assignment

opt generic-where-clause opt

GRAMMAR OF AN I N I T I A L I ZER DECLARAT ION

initializer-declaration → initializer-head generic-parameter-clause opt parameter-clausethrowsopt generic-where-clause opt initializer-body

initializer-declaration → initializer-head generic-parameter-clause opt parameter-clauserethrows generic-where-clause opt initializer-body

initializer-head → attributes opt declaration-modifiers opt initinitializer-head → attributes opt declaration-modifiers opt init ?initializer-head → attributes opt declaration-modifiers opt init !initializer-body → code-block

GRAMMAR OF ADE IN I T I A L I ZER DECLARAT ION

deinitializer-declaration → attributes opt deinit code-block

GRAMMAR OF AN EXTENS ION DECLARAT ION

extension-declaration → attributes opt access-level-modifier opt extension type-identifier type-inheritance-clause opt generic-where-clause opt extension-body

extension-body → { extension-members opt }extension-members → extension-member extension-members optextension-member → declaration | compiler-control-statement

Page 740: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF A SUBSCR IPT DECLARAT ION

subscript-declaration → subscript-head subscript-result generic-where-clause opt code-block

subscript-declaration → subscript-head subscript-result generic-where-clause opt getter-setter-block

subscript-declaration → subscript-head subscript-result generic-where-clause opt getter-setter-keyword-block

subscript-head → attributes opt declaration-modifiers opt subscript generic-parameter-clause opt parameter-clause

subscript-result → -> attributes opt type

GRAMMAR OF AN OPERATOR DECLARAT ION

operator-declaration → prefix-operator-declaration | postfix-operator-declaration | infix-operator-declaration

prefix-operator-declaration → prefix operator operatorpostfix-operator-declaration → postfix operator operatorinfix-operator-declaration → infix operator operator infix-operator-group optinfix-operator-group → : precedence-group-name

GRAMMAR OF A PRECEDENCE GROUP DECLARAT ION

precedence-group-declaration → precedencegroup precedence-group-name {precedence-group-attributes opt }

precedence-group-attributes → precedence-group-attribute precedence-group-attributesopt

precedence-group-attribute → precedence-group-relationprecedence-group-attribute → precedence-group-assignmentprecedence-group-attribute → precedence-group-associativityprecedence-group-relation → higherThan : precedence-group-namesprecedence-group-relation → lowerThan : precedence-group-namesprecedence-group-assignment → assignment : boolean-literalprecedence-group-associativity → associativity : leftprecedence-group-associativity → associativity : rightprecedence-group-associativity → associativity : noneprecedence-group-names → precedence-group-name | precedence-group-name ,

precedence-group-namesprecedence-group-name → identifier

GRAMMAR OF ADECLARAT ION MOD IF I ER

declaration-modifier → class | convenience | dynamic | final | infix | lazy |optional | override | postfix | prefix | required | static | unowned |unowned ( safe ) | unowned ( unsafe ) | weak

declaration-modifier → access-level-modifierdeclaration-modifier → mutation-modifier

Page 741: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

declaration-modifiers → declaration-modifier declaration-modifiers optaccess-level-modifier → private | private ( set )access-level-modifier → fileprivate | fileprivate ( set )access-level-modifier → internal | internal ( set )access-level-modifier → public | public ( set )access-level-modifier → open | open ( set )mutation-modifier → mutating | nonmutating

Attributes

GRAMMAR OF AN ATTR IBUTE

attribute → @ attribute-name attribute-argument-clause optattribute-name → identifierattribute-argument-clause → ( balanced-tokens opt )attributes → attribute attributes optbalanced-tokens → balanced-token balanced-tokens optbalanced-token → ( balanced-tokens opt )balanced-token → [ balanced-tokens opt ]balanced-token → { balanced-tokens opt }balanced-token → Anyidentifier,keyword,literal,oroperatorbalanced-token → Anypunctuationexcept ( , ) , [ , ] , { ,or }

Patterns

GRAMMAR OF A PATTERN

pattern → wildcard-pattern type-annotation optpattern → identifier-pattern type-annotation optpattern → value-binding-patternpattern → tuple-pattern type-annotation optpattern → enum-case-patternpattern → optional-patternpattern → type-casting-patternpattern → expression-pattern

GRAMMAR OF AW I LDCARD PATTERN

wildcard-pattern → _

Page 742: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

GRAMMAR OF AN I DENT I F I ER PATTERN

identifier-pattern → identifier

GRAMMAR OF A VALUE -B IND ING PATTERN

value-binding-pattern → var pattern | let pattern

GRAMMAR OF ATUPLE PATTERN

tuple-pattern → ( tuple-pattern-element-list opt )tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element , tuple-

pattern-element-listtuple-pattern-element → pattern | identifier : pattern

GRAMMAR OF AN ENUMERAT ION CASE PATTERN

enum-case-pattern → type-identifier opt . enum-case-name tuple-pattern opt

GRAMMAR OF AN OPT IONALPATTERN

optional-pattern → identifier-pattern ?

GRAMMAR OF ATYPE CAST ING PATTERN

type-casting-pattern → is-pattern | as-patternis-pattern → is typeas-pattern → pattern as type

GRAMMAR OF AN EXPRESS ION PATTERN

expression-pattern → expression

GenericParametersandArguments

GRAMMAR OF AGENER IC PARAMETER CLAUSE

generic-parameter-clause → < generic-parameter-list >generic-parameter-list → generic-parameter | generic-parameter , generic-parameter-

listgeneric-parameter → type-namegeneric-parameter → type-name : type-identifiergeneric-parameter → type-name : protocol-composition-type

Page 743: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

generic-where-clause → where requirement-listrequirement-list → requirement | requirement , requirement-listrequirement → conformance-requirement | same-type-requirementconformance-requirement → type-identifier : type-identifierconformance-requirement → type-identifier : protocol-composition-typesame-type-requirement → type-identifier == type

GRAMMAR OF AGENER IC ARGUMENT CLAUSE

generic-argument-clause → < generic-argument-list >generic-argument-list → generic-argument | generic-argument , generic-argument-listgeneric-argument → type

Page 744: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

RevisionHistory

Page 745: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

DocumentRevisionHistory

2019-09-10

UpdatedforSwift5.1.

Addedinformationaboutfunctionsthatspecifyaprotocolthattheirreturnvalueconformsto,insteadofprovidingaspecificnamedreturntype,totheOpaqueTypeschapter.

AddedinformationaboutpropertywrapperstothePropertyWrapperssection.

Addedinformationenumerationsandstructuresthatarefrozenforlibraryevolutiontothefrozensection.

AddedtheFunctionsWithanImplicitReturnandShorthandGetterDeclarationsectionswithinformationaboutfunctionsthatomitreturn.

AddedinformationaboutusingsubscriptsontypestotheTypeSubscriptssection.

UpdatedtheEnumerationCasePatternsection,nowthatanenumerationcasepatterncanmatchanoptionalvalue.

UpdatedtheMemberwiseInitializersforStructureTypessection,nowthatmemberwiseinitializerssupportomittingparametersforpropertiesthathaveadefaultvalue.

AddedinformationaboutdynamicmembersthatarelookedupbykeypathatruntimetothedynamicMemberLookupsection.

AddedmacCatalysttothelistoftargetenvironmentsinConditionalCompilationBlock.

UpdatedtheSelfTypesection,nowthatSelfcanbeusedtorefertothetypeintroducedbythecurrentclass,structure,orenumerationdeclaration.

Page 746: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

2019-03-25

UpdatedforSwift5.0.

AddedtheExtendedStringDelimiterssectionandupdatedtheStringLiteralssectionwithinformationaboutextendedstringdelimiters.

AddedthedynamicCallablesectionwithinformationaboutdynamicallycallinginstancesasfunctionsusingthedynamicCallableattribute.

AddedtheunknownandSwitchingOverFutureEnumerationCasessectionswithinformationabouthandlingfutureenumerationcasesinswitchstatementsusingtheunknownswitchcaseattribute.

Addedinformationabouttheidentitykeypath(\.self)totheKey-PathExpressionsection.

Addedinformationaboutusingthelessthan(<)operatorinplatformconditionstotheConditionalCompilationBlocksection.

2018-09-17

UpdatedforSwift4.2.

Addedinformationaboutaccessingallofanenumeration’scasestotheIteratingoverEnumerationCasessection.

Addedinformationabout#errorand#warningtotheCompile-TimeDiagnosticStatementsection.

AddedinformationaboutinliningtotheDeclarationAttributessectionundertheinlinableandusableFromInlineattributes.

AddedinformationaboutmembersthatarelookedupbynameatruntimetotheDeclarationAttributessectionunderthedynamicMemberLookupattribute.

Addedinformationabouttherequires_stored_property_initsandwarn_unqualified_accessattributestotheDeclarationAttributessection.

Page 747: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedinformationabouthowtoconditionallycompilecodedependingontheSwiftcompilerversionbeingusedtotheConditionalCompilationBlocksection.

Addedinformationabout#dsohandletotheLiteralExpressionsection.

2018-03-29

UpdatedforSwift4.1.

AddedinformationaboutsynthesizedimplementationsofequivalenceoperatorstotheEquivalenceOperatorssection.

AddedinformationaboutconditionalprotocolconformancetotheExtensionDeclarationsectionoftheDeclarationschapter,andtotheConditionallyConformingtoaProtocolsectionoftheProtocolschapter.

AddedinformationaboutrecursiveprotocolconstraintstotheUsingaProtocolinItsAssociatedType’sConstraintssection.

AddedinformationaboutthecanImport()andtargetEnvironment()platformconditionstoConditionalCompilationBlock.

2017-12-04

UpdatedforSwift4.0.3.

UpdatedtheKey-PathExpressionsection,nowthatkeypathssupportsubscriptcomponents.

2017-09-19

UpdatedforSwift4.0.

AddedinformationaboutexclusiveaccesstomemorytotheMemorySafetychapter.

AddedtheAssociatedTypeswithaGenericWhereClausesection,nowthatyoucanusegenericwhereclausestoconstrainassociatedtypes.

Page 748: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedinformationaboutmultilinestringliteralstotheStringLiteralssectionoftheStringsandCharacterschapter,andtotheStringLiteralssectionoftheLexicalStructurechapter.

UpdatedthediscussionoftheobjcattributeinDeclarationAttributes,nowthatthisattributeisinferredinfewerplaces.

AddedtheGenericSubscriptssection,nowthatsubscriptscanbegeneric.

UpdatedthediscussionintheProtocolCompositionsectionoftheProtocolschapter,andintheProtocolCompositionTypesectionoftheTypeschapter,nowthatprotocolcompositiontypescancontainasuperclassrequirement.

UpdatedthediscussionofprotocolextensionsinExtensionDeclarationnowthatfinalisn’tallowedinthem.

AddedinformationaboutpreconditionsandfatalerrorstotheAssertionsandPreconditionssection.

2017-03-27

UpdatedforSwift3.1.

AddedtheExtensionswithaGenericWhereClausesectionwithinformationaboutextensionsthatincluderequirements.

AddedexamplesofiteratingoverarangetotheFor-InLoopssection.

AddedanexampleoffailablenumericconversionstotheFailableInitializerssection.

AddedinformationtotheDeclarationAttributessectionaboutusingtheavailableattributewithaSwiftlanguageversion.

UpdatedthediscussionintheFunctionTypesectiontonotethatargumentlabelsarenotallowedwhenwritingafunctiontype.

UpdatedthediscussionofSwiftlanguageversionnumbersintheConditionalCompilationBlocksection,nowthatanoptionalpatchnumber

Page 749: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

isallowed.

UpdatedthediscussionintheFunctionTypesection,nowthatSwiftdistinguishesbetweenfunctionsthattakemultipleparametersandfunctionsthattakeasingleparameterofatupletype.

RemovedtheDynamicTypeExpressionsectionfromtheExpressionschapter,nowthattype(of:)isaSwiftstandardlibraryfunction.

2016-10-27

UpdatedforSwift3.0.1.

UpdatedthediscussionofweakandunownedreferencesintheAutomaticReferenceCountingchapter.

Addedinformationabouttheunowned,unowned(safe),andunowned(unsafe)declarationmodifiersintheDeclarationModifierssection.

AddedanotetotheTypeCastingforAnyandAnyObjectsectionaboutusinganoptionalvaluewhenavalueoftypeAnyisexpected.

UpdatedtheExpressionschaptertoseparatethediscussionofparenthesizedexpressionsandtupleexpressions.

2016-09-13

UpdatedforSwift3.0.

UpdatedthediscussionoffunctionsintheFunctionschapterandtheFunctionDeclarationsectiontonotethatallparametersgetanargumentlabelbydefault.

UpdatedthediscussionofoperatorsintheAdvancedOperatorschapter,nowthatyouimplementthemastypemethodsinsteadofasglobalfunctions.

Addedinformationabouttheopenandfileprivateaccess-levelmodifierstotheAccessControlchapter.

Page 750: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

UpdatedthediscussionofinoutintheFunctionDeclarationsectiontonotethatitappearsinfrontofaparameter’stypeinsteadofinfrontofaparameter’sname.

Updatedthediscussionofthe@noescapeand@autoclosureattributesintheEscapingClosuresandAutoclosuressectionsandtheAttributeschapternowthattheyaretypeattributes,ratherthandeclarationattributes.

AddedinformationaboutoperatorprecedencegroupstothePrecedenceforCustomInfixOperatorssectionoftheAdvancedOperatorschapter,andtothePrecedenceGroupDeclarationsectionoftheDeclarationschapter.

UpdateddiscussionthroughouttousemacOSinsteadofOSX,ErrorinsteadofErrorProtocol,andprotocolnamessuchasExpressibleByStringLiteralinsteadofStringLiteralConvertible.

UpdatedthediscussionintheGenericWhereClausessectionoftheGenericschapterandintheGenericParametersandArgumentschapter,nowthatgenericwhereclausesarewrittenattheendofadeclaration.

UpdatedthediscussionintheEscapingClosuressection,nowthatclosuresarenonescapingbydefault.

UpdatedthediscussionintheOptionalBindingsectionoftheTheBasicschapterandtheWhileStatementsectionoftheStatementschapter,nowthatif,while,andguardstatementsuseacomma-separatedlistofconditionswithoutwhereclauses.

AddedinformationaboutswitchcasesthathavemultiplepatternstotheSwitchsectionoftheControlFlowchapterandtheSwitchStatementsectionoftheStatementschapter.

UpdatedthediscussionoffunctiontypesintheFunctionTypesectionnowthatfunctionargumentlabelsarenolongerpartofafunction’stype.

UpdatedthediscussionofprotocolcompositiontypesintheProtocolCompositionsectionoftheProtocolschapterandintheProtocolCompositionTypesectionoftheTypeschaptertousethenewProtocol1&Protocol2syntax.

Page 751: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

UpdatedthediscussionintheDynamicTypeExpressionsectiontousethenewtype(of:)syntaxfordynamictypeexpressions.

Updatedthediscussionoflinecontrolstatementstousethe#sourceLocation(file:line:)syntaxintheLineControlStatementsection.

UpdatedthediscussioninFunctionsthatNeverReturntousethenewNevertype.

AddedinformationaboutplaygroundliteralstotheLiteralExpressionsection.

UpdatedthediscussionintheIn-OutParameterssectiontonotethatonlynonescapingclosurescancapturein-outparameters.

UpdatedthediscussionaboutdefaultparametersintheDefaultParameterValuessection,nowthattheycan’tbereorderedinfunctioncalls.

UpdatedattributeargumentstouseacolonintheAttributeschapter.

AddedinformationaboutthrowinganerrorinsidethecatchblockofarethrowingfunctiontotheRethrowingFunctionsandMethodssection.

AddedinformationaboutaccessingtheselectorofanObjective-Cproperty’sgetterorsettertotheSelectorExpressionsection.

AddedinformationtotheTypeAliasDeclarationsectionaboutgenerictypealiasesandusingtypealiasesinsideofprotocols.

UpdatedthediscussionoffunctiontypesintheFunctionTypesectiontonotethatparenthesesaroundtheparametertypesarerequired.

UpdatedtheAttributeschaptertonotethatthe@IBAction,@IBOutlet,and@NSManagedattributesimplythe@objcattribute.

Addedinformationaboutthe@GKInspectableattributetotheDeclarationAttributessection.

Page 752: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

UpdatedthediscussionofoptionalprotocolrequirementsintheOptionalProtocolRequirementssectiontoclarifythattheyareusedonlyincodethatinteroperateswithObjective-C.

RemovedthediscussionofexplicitlyusingletinfunctionparametersfromtheFunctionDeclarationsection.

RemovedthediscussionoftheBooleanprotocolfromtheStatementschapter,nowthattheprotocolhasbeenremovedfromtheSwiftstandardlibrary.

Correctedthediscussionofthe@NSApplicationMainattributeintheDeclarationAttributessection.

2016-03-21

UpdatedforSwift2.2.

AddedinformationabouthowtoconditionallycompilecodedependingontheversionofSwiftbeingusedtotheConditionalCompilationBlocksection.

AddedinformationabouthowtodistinguishbetweenmethodsorinitializerswhosenamesdifferonlybythenamesoftheirargumentstotheExplicitMemberExpressionsection.

Addedinformationaboutthe#selectorsyntaxforObjective-CselectorstotheSelectorExpressionsection.

UpdatedthediscussionofassociatedtypestousetheassociatedtypekeywordintheAssociatedTypesandProtocolAssociatedTypeDeclarationsections.

UpdatedinformationaboutinitializersthatreturnnilbeforetheinstanceisfullyinitializedintheFailableInitializerssection.

AddedinformationaboutcomparingtuplestotheComparisonOperatorssection.

Page 753: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedinformationaboutusingkeywordsasexternalparameternamestotheKeywordsandPunctuationsection.

Updatedthediscussionofthe@objcattributeintheDeclarationAttributessectiontonotethatenumerationsandenumerationcasescanusethisattribute.

UpdatedtheOperatorssectionwithdiscussionofcustomoperatorsthatcontainadot.

AddedanotetotheRethrowingFunctionsandMethodssectionthatrethrowingfunctionscan’tdirectlythrowerrors.

AddedanotetothePropertyObserverssectionaboutpropertyobserversbeingcalledwhenyoupassapropertyasanin-outparameter.

AddedasectionabouterrorhandlingtotheASwiftTourchapter.

UpdatedfiguresintheWeakReferencessectiontoshowthedeallocationprocessmoreclearly.

RemoveddiscussionofC-styleforloops,the++prefixandpostfixoperators,andthe--prefixandpostfixoperators.

Removeddiscussionofvariablefunctionargumentsandthespecialsyntaxforcurriedfunctions.

2015-10-20

UpdatedforSwift2.1.

UpdatedtheStringInterpolationandStringLiteralssectionsnowthatstringinterpolationscancontainstringliterals.

AddedtheEscapingClosuressectionwithinformationaboutthe@noescapeattribute.

UpdatedtheDeclarationAttributesandConditionalCompilationBlocksectionswithinformationabouttvOS.

Page 754: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Addedinformationaboutthebehaviorofin-outparameterstotheIn-OutParameterssection.

AddedinformationtotheCaptureListssectionabouthowvaluesspecifiedinclosurecapturelistsarecaptured.

UpdatedtheAccessingPropertiesThroughOptionalChainingsectiontoclarifyhowassignmentthroughoptionalchainingbehaves.

ImprovedthediscussionofautoclosuresintheAutoclosuressection.

Addedanexamplethatusesthe??operatortotheASwiftTourchapter.

2015-09-16

UpdatedforSwift2.0.

AddedinformationabouterrorhandlingtotheErrorHandlingchapter,theDoStatementsection,theThrowStatementsection,theDeferStatementsection,andtheTryOperatorsection.

UpdatedtheRepresentingandThrowingErrorssection,nowthatalltypescanconformtotheErrorTypeprotocol.

Addedinformationaboutthenewtry?keywordtotheConvertingErrorstoOptionalValuessection.

AddedinformationaboutrecursiveenumerationstotheRecursiveEnumerationssectionoftheEnumerationschapterandtheEnumerationswithCasesofAnyTypesectionoftheDeclarationschapter.

AddedinformationaboutAPIavailabilitycheckingtotheCheckingAPIAvailabilitysectionoftheControlFlowchapterandtheAvailabilityConditionsectionoftheStatementschapter.

AddedinformationaboutthenewguardstatementtotheEarlyExitsectionoftheControlFlowchapterandtheGuardStatementsectionoftheStatementschapter.

Page 755: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedinformationaboutprotocolextensionstotheProtocolExtensionssectionoftheProtocolschapter.

AddedinformationaboutaccesscontrolforunittestingtotheAccessLevelsforUnitTestTargetssectionoftheAccessControlchapter.

AddedinformationaboutthenewoptionalpatterntotheOptionalPatternsectionofthePatternschapter.

UpdatedtheRepeat-Whilesectionwithinformationabouttherepeat-whileloop.

UpdatedtheStringsandCharacterschapter,nowthatStringnolongerconformstotheCollectionTypeprotocolfromtheSwiftstandardlibrary.

AddedinformationaboutthenewSwiftstandardlibraryprint(_:separator:terminator)functiontothePrintingConstantsandVariablessection.

AddedinformationaboutthebehaviorofenumerationcaseswithStringrawvaluestotheImplicitlyAssignedRawValuessectionoftheEnumerationschapterandtheEnumerationswithCasesofaRaw-ValueTypesectionoftheDeclarationschapter.

Addedinformationaboutthe@autoclosureattribute—includingits@autoclosure(escaping)form—totheAutoclosuressection.

UpdatedtheDeclarationAttributessectionwithinformationaboutthe@availableand@warn_unused_resultattributes.

UpdatedtheTypeAttributessectionwithinformationaboutthe@conventionattribute.

AddedanexampleofusingmultipleoptionalbindingswithawhereclausetotheOptionalBindingsection.

AddedinformationtotheStringLiteralssectionabouthowconcatenatingstringliteralsusingthe+operatorhappensatcompiletime.

Page 756: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedinformationtotheMetatypeTypesectionaboutcomparingmetatypevaluesandusingthemtoconstructinstanceswithinitializerexpressions.

AddedanotetotheDebuggingwithAssertionssectionaboutwhenuser-definedassertionsaredisabled.

Updatedthediscussionofthe@NSManagedattributeintheDeclarationAttributessection,nowthattheattributecanbeappliedtocertaininstancemethods.

UpdatedtheVariadicParameterssection,nowthatvariadicparameterscanbedeclaredinanypositioninafunction’sparameterlist.

AddedinformationtotheOverridingaFailableInitializersectionabouthowanonfailableinitializercandelegateuptoafailableinitializerbyforce-unwrappingtheresultofthesuperclass’sinitializer.

AddedinformationaboutusingenumerationcasesasfunctionstotheEnumerationswithCasesofAnyTypesection.

AddedinformationaboutexplicitlyreferencinganinitializertotheInitializerExpressionsection.

AddedinformationaboutbuildconfigurationandlinecontrolstatementstotheCompilerControlStatementssection.

AddedanotetotheMetatypeTypesectionaboutconstructingclassinstancesfrommetatypevalues.

AddedanotetotheWeakReferencessectionaboutweakreferencesbeingunsuitableforcaching.

UpdatedanoteintheTypePropertiessectiontomentionthatstoredtypepropertiesarelazilyinitialized.

UpdatedtheCapturingValuessectiontoclarifyhowvariablesandconstantsarecapturedinclosures.

UpdatedtheDeclarationAttributessectiontodescribewhenyoucanapply

Page 757: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

the@objcattributetoclasses.

AddedanotetotheHandlingErrorssectionabouttheperformanceofexecutingathrowstatement.AddedsimilarinformationaboutthedostatementintheDoStatementsection.

UpdatedtheTypePropertiessectionwithinformationaboutstoredandcomputedtypepropertiesforclasses,structures,andenumerations.

UpdatedtheBreakStatementsectionwithinformationaboutlabeledbreakstatements.

UpdatedanoteinthePropertyObserverssectiontoclarifythebehaviorofwillSetanddidSetobservers.

AddedanotetotheAccessLevelssectionwithinformationaboutthescopeofprivateaccess.

AddedanotetotheWeakReferencessectionaboutthedifferencesinweakreferencesbetweengarbagecollectedsystemsandARC.

UpdatedtheSpecialCharactersinStringLiteralssectionwithamoreprecisedefinitionofUnicodescalars.

2015-04-08

UpdatedforSwift1.2.

SwiftnowhasanativeSetcollectiontype.Formoreinformation,seeSets.

@autoclosureisnowanattributeoftheparameterdeclaration,notitstype.Thereisalsoanew@noescapeparameterdeclarationattribute.Formoreinformation,seeDeclarationAttributes.

Typemethodsandpropertiesnowusethestatickeywordasadeclarationmodifier.FormoreinformationseeTypeVariableProperties.

Swiftnowincludestheas?andas!failabledowncastoperators.Formoreinformation,seeCheckingforProtocolConformance.

Page 758: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedanewguidesectionaboutStringIndices.

Removedtheoverflowdivision(&/)andoverflowremainder(&%)operatorsfromOverflowOperators.

Updatedtherulesforconstantandconstantpropertydeclarationandinitialization.Formoreinformation,seeConstantDeclaration.

UpdatedthedefinitionofUnicodescalarsinstringliterals.SeeSpecialCharactersinStringLiterals.

UpdatedRangeOperatorstonotethatahalf-openrangewiththesamestartandendindexwillbeempty.

UpdatedClosuresAreReferenceTypestoclarifythecapturingrulesforvariables.

UpdatedValueOverflowtoclarifytheoverflowbehaviorofsignedandunsignedintegers

UpdatedProtocolDeclarationtoclarifyprotocoldeclarationscopeandmembers.

UpdatedDefiningaCaptureListtoclarifythesyntaxforweakandunownedreferencesinclosurecapturelists.

UpdatedOperatorstoexplicitlymentionexamplesofsupportedcharactersforcustomoperators,suchasthoseintheMathematicalOperators,MiscellaneousSymbols,andDingbatsUnicodeblocks.

Constantscannowbedeclaredwithoutbeinginitializedinlocalfunctionscope.Theymusthaveasetvaluebeforefirstuse.Formoreinformation,seeConstantDeclaration.

Inaninitializer,constantpropertiescannowonlyassignavalueonce.Formoreinformation,seeAssigningConstantPropertiesDuringInitialization.

Multipleoptionalbindingscannowappearinasingleifstatementasacomma-separatedlistofassignmentexpressions.Formoreinformation,see

Page 759: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

OptionalBinding.

AnOptional-ChainingExpressionmustappearwithinapostfixexpression.

Protocolcastsarenolongerlimitedto@objcprotocols.

Typecaststhatcanfailatruntimenowusetheas?oras!operator,andtypecaststhatareguaranteednottofailusetheasoperator.Formoreinformation,seeType-CastingOperators.

2014-10-16

UpdatedforSwift1.1.

AddedafullguidetoFailableInitializers.

AddedadescriptionofFailableInitializerRequirementsforprotocols.

ConstantsandvariablesoftypeAnycannowcontainfunctioninstances.UpdatedtheexampleinTypeCastingforAnyandAnyObjecttoshowhowtocheckforandcasttoafunctiontypewithinaswitchstatement.

EnumerationswithrawvaluesnowhavearawValuepropertyratherthanatoRaw()methodandafailableinitializerwitharawValueparameterratherthanafromRaw()method.Formoreinformation,seeRawValuesandEnumerationswithCasesofaRaw-ValueType.

AddedanewreferencesectionaboutFailableInitializers,whichcantriggerinitializationfailure.

Customoperatorscannowcontainthe?character.UpdatedtheOperatorsreferencetodescribetherevisedrules.RemovedaduplicatedescriptionofthevalidsetofoperatorcharactersfromCustomOperators.

2014-08-18

NewdocumentthatdescribesSwift1.0,Apple’snewprogramminglanguageforbuildingiOSandOSXapps.

Page 760: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedanewsectionaboutInitializerRequirementsinprotocols.

AddedanewsectionaboutClass-OnlyProtocols.

AssertionsandPreconditionscannowusestringinterpolation.Removedanotetothecontrary.

UpdatedtheConcatenatingStringsandCharacterssectiontoreflectthefactthatStringandCharactervaluescannolongerbecombinedwiththeadditionoperator(+)oradditionassignmentoperator(+=).TheseoperatorsarenowusedonlywithStringvalues.UsetheStringtype’sappend(_:)methodtoappendasingleCharactervalueontotheendofastring.

AddedinformationabouttheavailabilityattributetotheDeclarationAttributessection.

Optionalsnolongerimplicitlyevaluatetotruewhentheyhaveavalueandfalsewhentheydonot,toavoidconfusionwhenworkingwithoptionalBoolvalues.Instead,makeanexplicitcheckagainstnilwiththe==or!=operatorstofindoutifanoptionalcontainsavalue.

SwiftnowhasaNil-CoalescingOperator(a??b),whichunwrapsanoptional’svalueifitexists,orreturnsadefaultvalueiftheoptionalisnil.

UpdatedandexpandedtheComparingStringssectiontoreflectanddemonstratethatstringandcharactercomparisonandprefix/suffixcomparisonarenowbasedonUnicodecanonicalequivalenceofextendedgraphemeclusters.

Youcannowtrytosetaproperty’svalue,assigntoasubscript,orcallamutatingmethodoroperatorthroughOptionalChaining.TheinformationaboutAccessingPropertiesThroughOptionalChaininghasbeenupdatedaccordingly,andtheexamplesofcheckingformethodcallsuccessinCallingMethodsThroughOptionalChaininghavebeenexpandedtoshowhowtocheckforpropertysettingsuccess.

AddedanewsectionaboutAccessingSubscriptsofOptionalTypethroughoptionalchaining.

Page 761: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

UpdatedtheAccessingandModifyinganArraysectiontonotethatyoucannolongerappendasingleitemtoanarraywiththe+=operator.Instead,usetheappend(_:)method,orappendasingle-itemarraywiththe+=operator.

AddedanotethatthestartvalueafortheRangeOperatorsa...banda..<bmustnotbegreaterthantheendvalueb.

RewrotetheInheritancechaptertoremoveitsintroductorycoverageofinitializeroverrides.Thischapternowfocusesmoreontheadditionofnewfunctionalityinasubclass,andthemodificationofexistingfunctionalitywithoverrides.Thechapter’sexampleofOverridingPropertyGettersandSettershasbeenrewrittentoshowhowtooverrideadescriptionproperty.(Theexamplesofmodifyinganinheritedproperty’sdefaultvalueinasubclassinitializerhavebeenmovedtotheInitializationchapter.)

UpdatedtheInitializerInheritanceandOverridingsectiontonotethatoverridesofadesignatedinitializermustnowbemarkedwiththeoverridemodifier.

UpdatedtheRequiredInitializerssectiontonotethattherequiredmodifierisnowwrittenbeforeeverysubclassimplementationofarequiredinitializer,andthattherequirementsforrequiredinitializerscannowbesatisfiedbyautomaticallyinheritedinitializers.

InfixOperatorMethodsnolongerrequirethe@infixattribute.

The@prefixand@postfixattributesforPrefixandPostfixOperatorshavebeenreplacedbyprefixandpostfixdeclarationmodifiers.

AddedanoteabouttheorderinwhichPrefixandPostfixOperatorsareappliedwhenbothaprefixandapostfixoperatorareappliedtothesameoperand.

OperatorfunctionsforCompoundAssignmentOperatorsnolongerusethe@assignmentattributewhendefiningthefunction.

TheorderinwhichmodifiersarespecifiedwhendefiningCustomOperatorshaschanged.Younowwriteprefixoperatorratherthanoperatorprefix,forexample.

Page 762: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

AddedinformationaboutthedynamicdeclarationmodifierinDeclarationModifiers.

AddedinformationabouthowtypeinferenceworkswithLiterals.

Addedmoreinformationaboutcurriedfunctions.

AddedanewchapteraboutAccessControl.

UpdatedtheStringsandCharacterschaptertoreflectthefactthatSwift’sCharactertypenowrepresentsasingleUnicodeextendedgraphemecluster.IncludesanewsectiononExtendedGraphemeClustersandmoreinformationaboutUnicodeScalarValuesandComparingStrings.

UpdatedtheStringLiteralssectiontonotethatUnicodescalarsinsidestringliteralsarenowwrittenas\u{n},wherenisahexadecimalnumberbetween0and10FFFF,therangeofUnicode’scodespace.

TheNSStringlengthpropertyisnowmappedontoSwift’snativeStringtypeasutf16Count,notutf16count.

Swift’snativeStringtypenolongerhasanuppercaseStringorlowercaseStringproperty.ThecorrespondingsectioninStringsandCharactershasbeenremoved,andvariouscodeexampleshavebeenupdated.

AddedanewsectionaboutInitializerParametersWithoutArgumentLabels.

AddedanewsectionaboutRequiredInitializers.

AddedanewsectionaboutOptionalTupleReturnTypes.

UpdatedtheTypeAnnotationssectiontonotethatmultiplerelatedvariablescanbedefinedonasinglelinewithonetypeannotation.

The@optional,@lazy,@final,and@requiredattributesarenowtheoptional,lazy,final,andrequiredDeclarationModifiers.

Page 763: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

Updatedtheentirebooktoreferto..<astheHalf-OpenRangeOperator(ratherthanthe“half-closedrangeoperator”).

UpdatedtheAccessingandModifyingaDictionarysectiontonotethatDictionarynowhasaBooleanisEmptyproperty.

ClarifiedthefulllistofcharactersthatcanbeusedwhendefiningCustomOperators.

nilandtheBooleanstrueandfalsearenowLiterals.

Swift’sArraytypenowhasfullvaluesemantics.UpdatedtheinformationaboutMutabilityofCollectionsandArraystoreflectthenewapproach.Alsoclarifiedtheassignmentandcopybehaviorforstringsarraysanddictionaries.

ArrayTypeShorthandSyntaxisnowwrittenas[SomeType]ratherthanSomeType[].

AddedanewsectionaboutDictionaryTypeShorthandSyntax,whichiswrittenas[KeyType:ValueType].

AddedanewsectionaboutHashValuesforSetTypes.

ExamplesofClosureExpressionsnowusetheglobalsorted(_:_:)functionratherthantheglobalsort(_:_:)function,toreflectthenewarrayvaluesemantics.

UpdatedtheinformationaboutMemberwiseInitializersforStructureTypestoclarifythatthememberwisestructureinitializerismadeavailableevenifastructure’sstoredpropertiesdonothavedefaultvalues.

Updatedto..<ratherthan..fortheHalf-OpenRangeOperator.

AddedanexampleofExtendingaGenericType.

Page 764: Welcome to Swift - Marek Piaseckimarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/pam/iOS... · Swift is friendly to new programmers. It’s an industrial-quality programming language

CopyrightandNotices

AppleInc.Copyright©2019AppleInc.

ThisdocumentismadeavailableunderaCreativeCommonsAttribution4.0International(CCBY4.0)License:https://creativecommons.org/licenses/by/4.0/

Nolicenses,expressorimplied,aregrantedwithrespecttoanyofthetechnologydescribedinthisdocument.Appleretainsallintellectualpropertyrightsassociatedwiththetechnologydescribedinthisdocument.

AppleInc.OneAppleParkWayCupertino,CA95014408-996-1010

Apple,theApplelogo,Bonjour,Cocoa,Logic,Mac,Numbers,Objective-C,OSX,Retina,Sand,Shake,andXcodearetrademarksofAppleInc.,registeredintheU.S.andothercountries.

SwiftandtvOSaretrademarksofAppleInc.

IOSisatrademarkorregisteredtrademarkofCiscointheU.S.andothercountriesandisusedunderlicense.

TimesisaregisteredtrademarkofHeidelbergerDruckmaschinenAG,availablefromLinotypeLibraryGmbH.