Welcome to Swift - autonom.iiar.pwr.wroc.pl · About Swift Swift is a new programming language for...

603

Transcript of Welcome to Swift - autonom.iiar.pwr.wroc.pl · About Swift Swift is a new programming language for...

  • WelcometoSwift

  • AboutSwift

    SwiftisanewprogramminglanguageforiOS,macOS,watchOS,andtvOSappsthatbuildsonthebestofCandObjective-C,withouttheconstraintsofCcompatibility.Swiftadoptssafeprogrammingpatternsandaddsmodernfeaturestomakeprogrammingeasier,moreflexible,andmorefun.Swift’scleanslate,backedbythematureandmuch-lovedCocoaandCocoaTouchframeworks,isanopportunitytoreimaginehowsoftwaredevelopmentworks.

    Swifthasbeenyearsinthemaking.ApplelaidthefoundationforSwiftbyadvancingourexistingcompiler,debugger,andframeworkinfrastructure.WesimplifiedmemorymanagementwithAutomaticReferenceCounting(ARC).Ourframeworkstack,builtonthesolidbaseofFoundationandCocoa,hasbeenmodernizedandstandardizedthroughout.Objective-Citselfhasevolvedtosupportblocks,collectionliterals,andmodules,enablingframeworkadoptionofmodernlanguagetechnologieswithoutdisruption.Thankstothisgroundwork,wecannowintroduceanewlanguageforthefutureofApplesoftwaredevelopment.

    SwiftfeelsfamiliartoObjective-Cdevelopers.ItadoptsthereadabilityofObjective-C’snamedparametersandthepowerofObjective-C’sdynamicobjectmodel.ItprovidesseamlessaccesstoexistingCocoaframeworksandmix-and-matchinteroperabilitywithObjective-Ccode.Buildingfromthiscommonground,Swiftintroducesmanynewfeaturesandunifiestheproceduralandobject-orientedportionsofthelanguage.

    Swiftisfriendlytonewprogrammers.Itisthefirstindustrial-qualitysystemsprogramminglanguagethatisasexpressiveandenjoyableasascriptinglanguage.Itsupportsplaygrounds,aninnovativefeaturethatallowsprogrammerstoexperimentwithSwiftcodeandseetheresultsimmediately,withouttheoverheadofbuildingandrunninganapp.

    SwiftcombinesthebestinmodernlanguagethinkingwithwisdomfromthewiderAppleengineeringculture.Thecompilerisoptimizedforperformance,andthelanguageisoptimizedfordevelopment,withoutcompromisingoneither.It’sdesignedtoscalefrom“hello,world”toanentireoperatingsystem.AllthismakesSwiftasoundfutureinvestmentfordevelopersandforApple.

    SwiftisafantasticwaytowriteiOS,macOS,watchOS,andtvOSapps,andwillcontinuetoevolvewithnewfeaturesandcapabilities.OurgoalsforSwiftareambitious.Wecan’twaittoseewhatyoucreatewithit.

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • ASwiftTour

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

    print("Hello,world!")

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

    ThistourgivesyouenoughinformationtostartwritingcodeinSwiftbyshowingyouhowtoaccomplishavarietyofprogrammingtasks.Don’tworryifyoudon’tunderstandsomething—everythingintroducedinthistourisexplainedindetailintherestofthisbook.

    NOTE

    OnaMac,downloadthePlaygroundanddouble-clickthefiletoopenitinXcode:https://developer.apple.com/go/?id=swift-tour

    SimpleValues

    Uselettomakeaconstantandvartomakeavariable.Thevalueofaconstantdoesn’tneedtobeknownatcompiletime,butyoumustassignitavalueexactlyonce.Thismeansyoucanuseconstantstonameavaluethatyoudetermineoncebutuseinmanyplaces.

    1 varmyVariable=42

    2 myVariable=50

    3 letmyConstant=42

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

    https://developer.apple.com/go/?id=swift-tourInstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • Iftheinitialvaluedoesn’tprovideenoughinformation(orifthereisnoinitialvalue),specifythetypebywritingitafterthevariable,separatedbyacolon.

    1 letimplicitInteger=70

    2 letimplicitDouble=70.0

    3 letexplicitDouble:Double=70

    EXPERIMEN T

    CreateaconstantwithanexplicittypeofFloatandavalueof4.

    Valuesareneverimplicitlyconvertedtoanothertype.Ifyouneedtoconvertavaluetoadifferenttype,explicitlymakeaninstanceofthedesiredtype.

    1 letlabel="Thewidthis"

    2 letwidth=94

    3 letwidthLabel=label+String(width)

    EXPERIMEN T

    TryremovingtheconversiontoStringfromthelastline.Whaterrordoyouget?

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

    1 letapples=3

    2 letoranges=5

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

    4 letfruitSummary="Ihave\(apples+oranges)piecesoffruit."

    EXPERIMEN T

    Use\()toincludeafloating-pointcalculationinastringandtoincludesomeone’snameinagreeting.

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

  • Createarraysanddictionariesusingbrackets([]),andaccesstheirelementsbywritingtheindexorkeyinbrackets.Acommaisallowedafterthelastelement.

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

    2 shoppingList[1]="bottleofwater"

    3

    4 varoccupations=[

    5 "Malcolm":"Captain",

    6 "Kaylee":"Mechanic",

    7 ]

    8 occupations["Jayne"]="PublicRelations"

    Tocreateanemptyarrayordictionary,usetheinitializersyntax.

    1 letemptyArray=[String]()

    2 letemptyDictionary=[String:Float]()

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

    1 shoppingList=[]

    2 occupations=[:]

    ControlFlow

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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 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 }

    print(teamScore)

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

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

    1 varoptionalString:String?="Hello"

    2 print(optionalString==nil)

    3

    4 varoptionalName:String?="JohnAppleseed"

    5 vargreeting="Hello!"

    6 ifletname=optionalName{

    7 greeting="Hello,\(name)"

    8 }

    EXPERIMEN T

    ChangeoptionalNametonil.Whatgreetingdoyouget?AddanelseclausethatsetsadifferentgreetingifoptionalNameisnil.

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • Iftheoptionalvalueisnil,theconditionalisfalseandthecodeinbracesisskipped.Otherwise,theoptionalvalueisunwrappedandassignedtotheconstantafterlet,whichmakestheunwrappedvalueavailableinsidetheblockofcode.

    Anotherwaytohandleoptionalvaluesistoprovideadefaultvalueusingthe??operator.Iftheoptionalvalueismissing,thedefaultvalueisusedinstead.

    1 letnickName:String?=nil

    2 letfullName:String="JohnAppleseed"

    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:

    print("Everythingtastesgoodinsoup.")

    }

    EXPERIMEN T

    Tryremovingthedefaultcase.Whaterrordoyouget?

    Noticehowletcanbeusedinapatterntoassignthevaluethatmatchedthepatterntoaconstant.

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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • Youusefor-intoiterateoveritemsinadictionarybyprovidingapairofnamestouseforeachkey-valuepair.Dictionariesareanunorderedcollection,sotheirkeysandvaluesareiteratedoverinanarbitraryorder.

    1 letinterestingNumbers=[

    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{

    largest=number

    }

    }

    }

    print(largest)

    EXPERIMEN T

    Addanothervariabletokeeptrackofwhichkindofnumberwasthelargest,aswellaswhatthatlargestnumberwas.

    Usewhiletorepeatablockofcodeuntilaconditionchanges.Theconditionofaloopcanbeattheendinstead,ensuringthattheloopisrunatleastonce.

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 1 varn=2

    2 whilen<100{

    3 n=n*2

    4 }

    5 print(n)

    6

    7 varm=2

    8 repeat{

    9 m=m*2

    }whilem<100

    print(m)

    Youcankeepanindexinaloopbyusing..<tomakearangeofindexes.

    1 vartotal=0

    2 foriin0..toseparatetheparameternamesandtypesfromthefunction’sreturntype.

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

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

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

    3 }

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

    EXPERIMEN T

    Removethedayparameter.Addaparametertoincludetoday’slunchspecialinthegreeting.

    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.

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXPodkreślenie

    InstruktorXPodkreślenie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXPodkreślenie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 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{

    min=score

    }

    sum+=score

    }

    return(min,max,sum)

    }

    letstatistics=calculateStatistics(scores:[5,3,100,3,9])

    print(statistics.sum)

    print(statistics.2)

    Functionscanalsotakeavariablenumberofarguments,collectingthemintoanarray.

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 1 funcsumOf(numbers:Int...)->Int{

    2 varsum=0

    3 fornumberinnumbers{

    4 sum+=number

    5 }

    6 returnsum

    7 }

    8 sumOf()

    9 sumOf(numbers:42,597,12)

    EXPERIMEN T

    Writeafunctionthatcalculatestheaverageofitsarguments.

    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.

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

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

    2 funcaddOne(number:Int)->Int{

    3 return1+number

    4 }

    5 returnaddOne

    6 }

    7 varincrement=makeIncrementer()

    8 increment(7)

    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{

    returnnumber<10

    }

    varnumbers=[20,19,7,12]

    hasAnyMatches(list:numbers,condition:lessThanTen)

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

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 1 numbers.map({

    2 (number:Int)->Intin

    3 letresult=3*number

    4 returnresult

    5 })

    EXPERIMEN T

    Rewritetheclosuretoreturnzeroforalloddnumbers.

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

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

    2 print(mappedNumbers)

    Youcanrefertoparametersbynumberinsteadofbyname—thisapproachisespeciallyusefulinveryshortclosures.Aclosurepassedasthelastargumenttoafunctioncanappearimmediatelyaftertheparentheses.Whenaclosureistheonlyargumenttoafunction,youcanomittheparenthesesentirely.

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

    2 print(sortedNumbers)

    ObjectsandClasses

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

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 1 classShape{

    2 varnumberOfSides=0

    3 funcsimpleDescription()->String{

    4 return"Ashapewith\(numberOfSides)sides."

    5 }

    6 }

    EXPERIMEN T

    Addaconstantpropertywithlet,andaddanothermethodthattakesanargument.

    Createaninstanceofaclassbyputtingparenthesesaftertheclassname.Usedotsyntaxtoaccessthepropertiesandmethodsoftheinstance.

    1 varshape=Shape()

    2 shape.numberOfSides=7

    3 varshapeDescription=shape.simpleDescription()

    ThisversionoftheShapeclassismissingsomethingimportant:aninitializertosetuptheclasswhenaninstanceiscreated.Useinittocreateone.

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 1 classNamedShape{

    2 varnumberOfSides:Int=0

    3 varname:String

    4

    5 init(name:String){

    6 self.name=name

    7 }

    8

    9 funcsimpleDescription()->String{

    return"Ashapewith\(numberOfSides)sides."

    }

    }

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

    Usedeinittocreateadeinitializerifyouneedtoperformsomecleanupbeforetheobjectisdeallocated.

    Subclassesincludetheirsuperclassnameaftertheirclassname,separatedbyacolon.Thereisnorequirementforclassestosubclassanystandardrootclass,soyoucanincludeoromitasuperclassasneeded.

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

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 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

    funcarea()->Double{

    returnsideLength*sideLength

    }

    overridefuncsimpleDescription()->String{

    return"Asquarewithsidesoflength\(sideLength)."

    }

    }

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

    test.area()

    test.simpleDescription()

    EXPERIMEN T

    MakeanothersubclassofNamedShapecalledCirclethattakesaradiusandanameasargumentstoitsinitializer.Implementanarea()andasimpleDescription()methodontheCircleclass.

    Inadditiontosimplepropertiesthatarestored,propertiescanhaveagetterandasetter.

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 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

    varperimeter:Double{

    get{

    return3.0*sideLength

    }

    set{

    sideLength=newValue/3.0

    }

    }

    overridefuncsimpleDescription()->String{

    return"Anequilateraltrianglewithsidesoflength\(sideLength)."

    }

    }

    vartriangle=EquilateralTriangle(sideLength:3.1,name:"atriangle")

    print(triangle.perimeter)

    triangle.perimeter=9.9

    print(triangle.sideLength)

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • Inthesetterforperimeter,thenewvaluehastheimplicitnamenewValue.Youcanprovideanexplicitnameinparenthesesafterset.

    NoticethattheinitializerfortheEquilateralTriangleclasshasthreedifferentsteps:

    1. Settingthevalueofpropertiesthatthesubclassdeclares.2. Callingthesuperclass’sinitializer.3. Changingthevalueofpropertiesdefinedbythesuperclass.Anyadditionalsetupworkthatuses

    methods,getters,orsetterscanalsobedoneatthispoint.

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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 1 classTriangleAndSquare{

    2 vartriangle:EquilateralTriangle{

    3 willSet{

    4 square.sideLength=newValue.sideLength

    5 }

    6 }

    7 varsquare:Square{

    8 willSet{

    9 triangle.sideLength=newValue.sideLength

    }

    }

    init(size:Double,name:String){

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

    triangle=EquilateralTriangle(sideLength:size,name:name)

    }

    }

    vartriangleAndSquare=TriangleAndSquare(size:10,name:"anothertestshape")

    print(triangleAndSquare.square.sideLength)

    print(triangleAndSquare.triangle.sideLength)

    triangleAndSquare.square=Square(sideLength:50,name:"largersquare")

    print(triangleAndSquare.triangle.sideLength)

    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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

  • 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 funcsimpleDescription()->String{

    6 switchself{

    7 case.ace:

    8 return"ace"

    9 case.jack:

    return"jack"

    case.queen:

    return"queen"

    case.king:

    return"king"

    default:

    returnString(self.rawValue)

    }

    }

    }

    letace=Rank.ace

    letaceRawValue=ace.rawValue

  • EXPERIMEN T

    WriteafunctionthatcomparestwoRankvaluesbycomparingtheirrawvalues.

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

    Usetheinit?(rawValue:)initializertomakeaninstanceofanenumerationfromarawvalue.

    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 funcsimpleDescription()->String{

    4 switchself{

    5 case.spades:

    6 return"spades"

    7 case.hearts:

    8 return"hearts"

    9 case.diamonds:

    return"diamonds"

    case.clubs:

    return"clubs"

    }

    }

    }

    lethearts=Suit.hearts

    letheartsDescription=hearts.simpleDescription()

    EXPERIMEN T

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

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

    Ifanenumerationhasrawvalues,thosevaluesaredeterminedaspartofthedeclaration,whichmeanseveryinstanceofaparticularenumerationcasealwayshasthesamerawvalue.Anotherchoiceforenumerationcasesistohavevaluesassociatedwiththecase—thesevaluesaredeterminedwhenyoumaketheinstance,andtheycanbedifferentforeachinstanceofanenumerationcase.Youcanthink

  • oftheassociatedvaluesasbehavinglikestoredpropertiesoftheenumerationcaseinstance.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.")

    8

    9 switchsuccess{

    caselet.result(sunrise,sunset):

    print("Sunriseisat\(sunrise)andsunsetisat\(sunset).")

    caselet.failure(message):

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

    }

    EXPERIMEN T

    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=threeOfSpades.simpleDescription()

    EXPERIMEN T

    AddamethodtoCardthatcreatesafulldeckofcards,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()

    letaDescription=a.simpleDescription

    structSimpleStructure:ExampleProtocol{

    varsimpleDescription:String="Asimplestructure"

    mutatingfuncadjust(){

    simpleDescription+="(adjusted)"

    }

    }

    varb=SimpleStructure()

    b.adjust()

    letbDescription=b.simpleDescription

    EXPERIMEN T

    Writeanenumerationthatconformstothisprotocol.

    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)

    EXPERIMEN T

    WriteanextensionfortheDoubletypethataddsanabsoluteValueproperty.

    Youcanuseaprotocolnamejustlikeanyothernamedtype—forexample,tocreateacollectionofobjectsthathavedifferenttypesbutthatallconformtoasingleprotocol.Whenyouworkwithvalueswhosetypeisaprotocoltype,methodsoutsidetheprotocoldefinitionarenotavailable.

    1 letprotocolValue:ExampleProtocol=a

    2 print(protocolValue.simpleDescription)

    3 //print(protocolValue.anotherProperty)//Uncommenttoseetheerror

    EventhoughthevariableprotocolValuehasaruntimetypeofSimpleClass,thecompilertreatsitasthegiventypeofExampleProtocol.Thismeansthatyoucan’taccidentallyaccessmethodsorpropertiesthattheclassimplementsinadditiontoitsprotocolconformance.

    ErrorHandling

    YourepresenterrorsusinganytypethatadoptstheErrorprotocol.

  • 1 enumPrinterError:Error{

    2 caseoutOfPaper

    3 casenoToner

    4 caseonFire

    5 }

    Usethrowtothrowanerrorandthrowstomarkafunctionthatcanthrowanerror.Ifyouthrowanerrorinafunction,thefunctionreturnsimmediatelyandthecodethatcalledthefunctionhandlestheerror.

    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:"BiSheng")

    3 print(printerResponse)

    4 }catch{

    5 print(error)

    6 }

    EXPERIMEN T

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

  • Youcanprovidemultiplecatchblocksthathandlespecificerrors.Youwriteapatternaftercatchjustasyoudoaftercaseinaswitch.

    1 do{

    2 letprinterResponse=trysend(job:1440,toPrinter:"Gutenberg")

    3 print(printerResponse)

    4 }catchPrinterError.onFire{

    5 print("I'lljustputthisoverhere,withtherestofthefire.")

    6 }catchletprinterErrorasPrinterError{

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

    8 }catch{

    9 print(error)

    }

    EXPERIMEN T

    Addcodetothrowanerrorinsidethedoblock.Whatkindoferrordoyouneedtothrowsothattheerrorishandledbythefirstcatchblock?Whataboutthesecondandthirdblocks?

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

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

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

    Usedefertowriteablockofcodethatisexecutedafterallothercodeinthefunction,justbeforethefunctionreturns.Thecodeisexecutedregardlessofwhetherthefunctionthrowsanerror.Youcanusedefertowritesetupandcleanupcodenexttoeachother,eventhoughtheyneedtobeexecutedatdifferenttimes.

  • 1 varfridgeIsOpen=false

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

    3

    4 funcfridgeContains(_food:String)->Bool{

    5 fridgeIsOpen=true

    6 defer{

    7 fridgeIsOpen=false

    8 }

    9

    letresult=fridgeContent.contains(food)

    returnresult

    }

    fridgeContains("banana")

    print(fridgeIsOpen)

    Generics

    Writeanameinsideanglebracketstomakeagenericfunctionortype.

    1 funcmakeArray(repeatingitem:Item,numberOfTimes:Int)->[Item]{

    2 varresult=[Item]()

    3 for_in0..

  • Youcanmakegenericformsoffunctionsandmethods,aswellasclasses,enumerations,andstructures.

    1 //ReimplementtheSwiftstandardlibrary'soptionaltype

    2 enumOptionalValue{

    3 casenone

    4 casesome(Wrapped)

    5 }

    6 varpossibleInteger:OptionalValue=.none

    7 possibleInteger=.some(100)

    Usewhererightbeforethebodytospecifyalistofrequirements—forexample,torequirethetypetoimplementaprotocol,torequiretwotypestobethesame,ortorequireaclasstohaveaparticularsuperclass.

    1 funcanyCommonElements(_lhs:T,_rhs:U)->Bool

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

    3 forlhsIteminlhs{

    4 forrhsIteminrhs{

    5 iflhsItem==rhsItem{

    6 returntrue

    7 }

    8 }

    9 }

    returnfalse

    }

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

  • EXPERIMEN T

    ModifytheanyCommonElements(_:_:)functiontomakeafunctionthatreturnsanarrayoftheelementsthatanytwosequenceshaveincommon.

    Writingisthesameaswriting...whereT:Equatable>.

  • LanguageGuide

  • TheBasics

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

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

    LikeC,Swiftusesvariablestostoreandrefertovaluesbyanidentifyingname.Swiftalsomakesextensiveuseofvariableswhosevaluescannotbechanged.Theseareknownasconstants,andaremuchmorepowerfulthanconstantsinC.ConstantsareusedthroughoutSwifttomakecodesaferandclearerinintentwhenyouworkwithvaluesthatdonotneedtochange.

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

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

    Swiftisatype-safelanguage,whichmeansthelanguagehelpsyoutobeclearaboutthetypesofvaluesyourcodecanworkwith.IfpartofyourcodeexpectsaString,typesafetypreventsyoufrompassingitanIntbymistake.Likewise,typesafetypreventsyoufromaccidentallypassinganoptionalStringtoapieceofcodethatexpectsanonoptionalString.Typesafetyhelpsyoucatchandfixerrorsasearlyaspossibleinthedevelopmentprocess.

    ConstantsandVariables

    Constantsandvariablesassociateaname(suchasmaximumNumberOfLoginAttemptsorwelcomeMessage)withavalueofaparticulartype(suchasthenumber10orthestring"Hello").Thevalueofaconstantcannotbechangedonceitisset,whereasavariablecanbesettoadifferentvalueinthefuture.

    DeclaringConstantsandVariables

  • Constantsandvariablesmustbedeclaredbeforetheyareused.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

    Ifastoredvalueinyourcodeisnotgoingtochange,alwaysdeclareitasaconstantwiththeletkeyword.Usevariablesonlyforstoringvaluesthatneedtobeabletochange.

    TypeAnnotations

    Youcanprovideatypeannotationwhenyoudeclareaconstantorvariable,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

    Itisrarethatyouneedtowritetypeannotationsinpractice.Ifyouprovideaninitialvalueforaconstantorvariableatthepointthatitisdefined,Swiftcanalmostalwaysinferthetypetobeusedforthatconstantorvariable,asdescribedinTypeSafetyandTypeInference.InthewelcomeMessageexampleabove,noinitialvalueisprovided,andsothetypeofthewelcomeMessagevariableisspecifiedwithatypeannotationratherthanbeinginferredfromaninitialvalue.

    NamingConstantsandVariables

    Constantandvariablenamescancontainalmostanycharacter,includingUnicodecharacters:

    1 letπ=3.14159

    2 let你好="你好世界"

    3 let ="dogcow"

    Constantandvariablenamescannotcontainwhitespacecharacters,mathematicalsymbols,arrows,private-use(orinvalid)Unicodecodepoints,orline-andbox-drawingcharacters.Norcantheybeginwithanumber,althoughnumbersmaybeincludedelsewherewithinthename.

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

    NOTE

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

    Youcanchangethevalueofanexistingvariabletoanothervalueofacompatibletype.Inthis

  • example,thevalueoffriendlyWelcomeischangedfrom"Hello!"to"Bonjour!":

    1 varfriendlyWelcome="Hello!"

    2 friendlyWelcome="Bonjour!"

    3 //friendlyWelcomeisnow"Bonjour!"

    Unlikeavariable,thevalueofaconstantcannotbechangedonceitisset.Attemptingtodosoisreportedasanerrorwhenyourcodeiscompiled:

    1 letlanguageName="Swift"

    2 languageName="Swift++"

    3 //Thisisacompile-timeerror:languageNamecannotbechanged.

    PrintingConstantsandVariables

    Youcanprintthecurrentvalueofaconstantorvariablewiththeprint(_: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!"

  • 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.

    Semicolons

    Unlikemanyotherlanguages,Swiftdoesnotrequireyoutowriteasemicolon(;)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.

    IntegerBounds

    Youcanaccesstheminimumandmaximumvaluesofeachintegertypewithitsminandmaxproperties:

    1 letminValue=UInt8.min//minValueisequalto0,andisoftypeUInt8

    2 letmaxValue=UInt8.max//maxValueisequalto255,andisoftypeUInt8

    Thevaluesofthesepropertiesareoftheappropriate-sizednumbertype(suchasUInt8intheexampleabove)andcanthereforebeusedinexpressionsalongsideothervaluesofthesametype.

    Int

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

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

    Ona32-bitplatform,IntisthesamesizeasInt32.•Ona64-bitplatform,IntisthesamesizeasInt64.•

  • UInt

    Swiftalsoprovidesanunsignedintegertype,UInt,whichhasthesamesizeasthecurrentplatform’snativewordsize:

    NOTE

    UseUIntonlywhenyouspecificallyneedanunsignedintegertypewiththesamesizeastheplatform’snativewordsize.Ifthisisnotthecase,Intispreferred,evenwhenthevaluestobestoredareknowntobenon-negative.AconsistentuseofIntforintegervaluesaidscodeinteroperability,avoidstheneedtoconvertbetweendifferentnumbertypes,andmatchesintegertypeinference,asdescribedinTypeSafetyandTypeInference.

    Floating-PointNumbers

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

    Floating-pointtypescanrepresentamuchwiderrangeofvaluesthanintegertypes,andcanstorenumbersthataremuchlargerorsmallerthancanbestoredinanInt.Swiftprovidestwosignedfloating-pointnumbertypes:

    NOTE

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

    TypeSafetyandTypeInference

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

    Ona32-bitplatform,UIntisthesamesizeasUInt32.•Ona64-bitplatform,UIntisthesamesizeasUInt64.•

    Doublerepresentsa64-bitfloating-pointnumber.•Floatrepresentsa32-bitfloating-pointnumber.•

  • BecauseSwiftistypesafe,itperformstypecheckswhencompilingyourcodeandflagsanymismatchedtypesaserrors.Thisenablesyoutocatchandfixerrorsasearlyaspossibleinthedevelopmentprocess.

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

    Becauseoftypeinference,SwiftrequiresfarfewertypedeclarationsthanlanguagessuchasCorObjective-C.Constantsandvariablesarestillexplicitlytyped,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.

  • NumericLiterals

    Integerliteralscanbewrittenas:

    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:

    Forhexadecimalnumberswithanexponentofexp,thebasenumberismultipliedby2exp:

    Allofthesefloating-pointliteralshaveadecimalvalueof12.1875:

    Adecimalnumber,withnoprefix•Abinarynumber,witha0bprefix•Anoctalnumber,witha0oprefix•Ahexadecimalnumber,witha0xprefix•

    1.25e2means1.25x102,or125.0.•

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

    0xFp2means15x22,or60.0.•

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

  • 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,eveniftheyareknowntobenon-negative.Usingthedefaultintegertypeineverydaysituationsmeansthatintegerconstantsandvariablesareimmediatelyinteroperableinyourcodeandwillmatchtheinferredtypeforintegerliteralvalues.

    Useotherintegertypesonlywhentheyarespecificallyneededforthetaskathand,becauseofexplicitly-sizeddatafromanexternalsource,orforperformance,memoryusage,orothernecessaryoptimization.Usingexplicitly-sizedtypesinthesesituationshelpstocatchanyaccidentalvalueoverflowsandimplicitlydocumentsthenatureofthedatabeingused.

    IntegerConversion

    Therangeofnumbersthatcanbestoredinanintegerconstantorvariableisdifferentforeachnumerictype.AnInt8constantorvariablecanstorenumbersbetween-128and127,whereasaUInt8constantorvariablecanstorenumbersbetween0and255.Anumberthatwillnotfitintoaconstantorvariableofasizedintegertypeisreportedasanerrorwhenyourcodeiscompiled:

  • 1 letcannotBeNegative:UInt8=-1

    2 //UInt8cannotstorenegativenumbers,andsothiswillreportanerror

    3 lettooBig:Int8=Int8.max+1

    4 //Int8cannotstoreanumberlargerthanitsmaximumvalue,

    5 //andsothiswillalsoreportanerror

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

    Toconvertonespecificnumbertypetoanother,youinitializeanewnumberofthedesiredtypewiththeexistingvalue.Intheexamplebelow,theconstanttwoThousandisoftypeUInt16,whereastheconstantoneisoftypeUInt8.Theycannotbeaddedtogetherdirectly,becausetheyarenotofthesametype.Instead,thisexamplecallsUInt16(one)tocreateanewUInt16initializedwiththevalueofone,andusesthisvalueinplaceoftheoriginal:

    1 lettwoThousand:UInt16=2_000

    2 letone:UInt8=1

    3 lettwoThousandAndOne=twoThousand+UInt16(one)

    BecausebothsidesoftheadditionarenowoftypeUInt16,theadditionisallowed.Theoutputconstant(twoThousandAndOne)isinferredtobeoftypeUInt16,becauseitisthesumoftwoUInt16values.

    SomeType(ofInitialValue)isthedefaultwaytocalltheinitializerofaSwifttypeandpassinaninitialvalue.Behindthescenes,UInt16hasaninitializerthatacceptsaUInt8value,andsothisinitializerisusedtomakeanewUInt16fromanexistingUInt8.Youcan’tpassinanytypehere,however—ithastobeatypeforwhichUInt16providesaninitializer.Extendingexistingtypestoprovideinitializersthatacceptnewtypes(includingyourowntypedefinitions)iscoveredinExtensions.

    IntegerandFloating-PointConversion

    Conversionsbetweenintegerandfloating-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,becausenumberliteralsdonothaveanexplicittypeinandofthemselves.Theirtypeisinferredonlyatthepointthattheyareevaluatedbythecompiler.

    TypeAliases

    Typealiasesdefineanalternativenameforanexistingtype.Youdefinetypealiaseswiththetypealiaskeyword.

    Typealiasesareusefulwhenyouwanttorefertoanexistingtypebyanamethatiscontextuallymoreappropriate,suchaswhenworkingwithdataofaspecificsizefromanexternalsource:

    typealiasAudioSample=UInt16

    Onceyoudefineatypealias,youcanusethealiasanywhereyoumightusetheoriginalname:

    1 varmaxAmplitudeFound=AudioSample.min

    2 //maxAmplitudeFoundisnow0

  • Here,AudioSampleisdefinedasanaliasforUInt16.Becauseitisanalias,thecalltoAudioSample.minactuallycallsUInt16.min,whichprovidesaninitialvalueof0forthemaxAmplitudeFoundvariable.

    Booleans

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

    1 letorangesAreOrange=true

    2 letturnipsAreDelicious=false

    ThetypesoforangesAreOrangeandturnipsAreDelicioushavebeeninferredasBoolfromthefactthattheywereinitializedwithBooleanliteralvalues.AswithIntandDoubleabove,youdon’tneedtodeclareconstantsorvariablesasBoolifyousetthemtotrueorfalseassoonasyoucreatethem.TypeinferencehelpsmakeSwiftcodemoreconciseandreadablewhenitinitializesconstantsorvariableswithothervalueswhosetypeisalreadyknown.

    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.

    AswithotherexamplesoftypesafetyinSwift,thisapproachavoidsaccidentalerrorsandensuresthattheintentionofaparticularsectionofcodeisalwaysclear.

    Tuples

    Tuplesgroupmultiplevaluesintoasinglecompoundvalue.Thevalueswithinatuplecanbeofanytypeanddonothavetobeofthesametypeaseachother.

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

    1 lethttp404Error=(404,"NotFound")

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

    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)")

    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.Formoreinformation,seeFunctionswithMultipleReturnValues.

    NOTE

    Tuplesareusefulfortemporarygroupsofrelatedvalues.Theyarenotsuitedtothecreationofcomplexdatastructures.Ifyourdatastructureislikelytopersistbeyondatemporaryscope,modelitasaclassorstructure,ratherthanasatuple.Formoreinformation,seeClassesandStructures.

    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’scallerknowsthereisaspecialvaluetotestagainstandrememberstocheckforit.Swift’soptionalsletyouindicatetheabsenceofavalueforanytypeatall,withouttheneedforspecialconstants.

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

    TheexamplebelowusestheinitializertotrytoconvertaStringintoanInt:

    1 letpossibleNumber="123"

    2 letconvertedNumber=Int(possibleNumber)

    3 //convertedNumberisinferredtobeoftype"Int?",or"optionalInt"

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

  • nil

    Yousetanoptionalvariabletoavaluelessstatebyassigningitthespecialvaluenil:

    1 varserverResponseCode:Int?=404

    2 //serverResponseCodecontainsanactualIntvalueof404

    3 serverResponseCode=nil

    4 //serverResponseCodenowcontainsnovalue

    NOTE

    nilcannotbeusedwithnonoptionalconstantsandvariables.Ifaconstantorvariableinyourcodeneedstoworkwiththeabsenceofavalueundercertainconditions,alwaysdeclareitasanoptionalvalueoftheappropriatetype.

    Ifyoudefineanoptionalvariablewithoutprovidingadefaultvalue,thevariableisautomaticallysettonilforyou:

    1 varsurveyAnswer:String?

    2 //surveyAnswerisautomaticallysettonil

    NOTE

    Swift’snilisnotthesameasnilinObjective-C.InObjective-C,nilisapointertoanonexistentobject.InSwift,nilisnotapointer—itistheabsenceofavalueofacertaintype.Optionalsofanytypecanbesettonil,notjustobjecttypes.

    IfStatementsandForcedUnwrapping

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

    Ifanoptionalhasavalue,itisconsideredtobe“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."

    Formoreontheifstatement,seeControlFlow.

    NOTE

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

    OptionalBinding

    Youuseoptionalbindingtofindoutwhetheranoptionalcontainsavalue,andifso,tomakethatvalueavailableasatemporaryconstantorvariable.Optionalbindingcanbeusedwithifandwhilestatementstocheckforavalueinsideanoptional,andtoextractthatvalueintoaconstantorvariable,aspartofasingleaction.ifandwhilestatementsaredescribedinmoredetailinControlFlow.

    Writeanoptionalbindingforanifstatementasfollows:

    iflet constantName = someOptional {

    statements

    }

  • YoucanrewritethepossibleNumberexamplefromtheOptionalssectiontouseoptionalbindingratherthanforcedunwrapping:

    1 ifletactualNumber=Int(possibleNumber){

    2 print("\"\(possibleNumber)\"hasanintegervalueof\(actualNumber)")

    3 }else{

    4 print("\"\(possibleNumber)\"couldnotbeconvertedtoaninteger")

    5 }

    6 //Prints""123"hasanintegervalueof123"

    Thiscodecanbereadas:

    “IftheoptionalIntreturnedbyInt(possibleNumber)containsavalue,setanewconstantcalledactualNumbertothevaluecontainedintheoptional.”

    Iftheconversionissuccessful,theactualNumberconstantbecomesavailableforusewithinthefirstbranchoftheifstatement.Ithasalreadybeeninitializedwiththevaluecontainedwithintheoptional,andsothereisnoneedtousethe!suffixtoaccessitsvalue.Inthisexample,actualNumberissimplyusedtoprinttheresultoftheconversion.

    Youcanusebothconstantsandvariableswithoptionalbinding.IfyouwantedtomanipulatethevalueofactualNumberwithinthefirstbranchoftheifstatement,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")

    }

    }

    }

    //Prints"4<42<100"

    NOTE

    Constantsandvariablescreatedwithoptionalbindinginanifstatementareavailableonlywithinthebodyoftheifstatement.Incontrast,theconstantsandvariablescreatedwithaguardstatementareavailableinthelinesofcodethatfollowtheguardstatement,asdescribedinEarlyExit.

    ImplicitlyUnwrappedOptionals

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

    Sometimesitisclearfromaprogram’sstructurethatanoptionalwillalwayshaveavalue,afterthatvalueisfirstset.Inthesecases,itisusefultoremovetheneedtocheckandunwraptheoptional’svalueeverytimeitisaccessed,becauseitcanbesafelyassumedtohaveavalueallofthetime.

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

  • afterthetypethatyouwanttomakeoptional.

    Implicitlyunwrappedoptionalsareusefulwhenanoptional’svalueisconfirmedtoexistimmediatelyaftertheoptionalisfirstdefinedandcandefinitelybeassumedtoexistateverypointthereafter.TheprimaryuseofimplicitlyunwrappedoptionalsinSwiftisduringclassinitialization,asdescribedinUnownedReferencesandImplicitlyUnwrappedOptionalProperties.

    Animplicitlyunwrappedoptionalisanormaloptionalbehindthescenes,butcanalsobeusedlikeanonoptionalvalue,withouttheneedtounwraptheoptionalvalueeachtimeitisaccessed.ThefollowingexampleshowsthedifferenceinbehaviorbetweenanoptionalstringandanimplicitlyunwrappedoptionalstringwhenaccessingtheirwrappedvalueasanexplicitString:

    1 letpossibleString:String?="Anoptionalstring."

    2 letforcedString:String=possibleString!//requiresanexclamationmark

    3

    4 letassumedString:String!="Animplicitlyunwrappedoptionalstring."

    5 letimplicitString:String=assumedString//noneedforanexclamationmark

    Youcanthinkofanimplicitlyunwrappedoptionalasgivingpermissionfortheoptionaltobeunwrappedautomaticallywheneveritisused.Ratherthanplacinganexclamationmarkaftertheoptional’snameeachtimeyouuseit,youplaceanexclamationmarkaftertheoptional’stypewhenyoudeclareit.

    NOTE

    Ifanimplicitlyunwrappedoptionalisnilandyoutrytoaccessitswrappedvalue,you’lltriggeraruntimeerror.Theresultisexactlythesameasifyouplaceanexclamationmarkafteranormaloptionalthatdoesnotcontainavalue.

    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

    Donotuseanimplicitlyunwrappedoptionalwhenthereisapossibilityofavariablebecomingnilatalaterpoint.Alwaysuseanormaloptionaltypeifyouneedtocheckforanilvalueduringthelifetimeofavariable.

    ErrorHandling

    Youuseerrorhandlingtorespondtoerrorconditionsyourprogrammayencounterduringexecution.

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

    Whenafunctionencountersanerrorcondition,itthrowsanerror.Thatfunction’scallercanthencatchtheerrorandrespondappropriately.

    1 funccanThrowAnError()throws{

    2 //thisfunctionmayormaynotthrowanerror

    3 }

    Afunctionindicatesthatitcanthrowanerrorbyincludingthethrowskeywordinitsdeclaration.Whenyoucallafunctionthatcanthrowanerror,youprependthetrykeywordtotheexpression.

    Swiftautomaticallypropagateserrorsoutoftheircurrentscopeuntiltheyarehandledbyacatchclause.

  • 1 do{

    2 trycanThrowAnError()

    3 //noerrorwasthrown

    4 }catch{

    5 //anerrorwasthrown

    6 }

    Adostatementcreatesanewcontainingscope,whichallowserrorstobepropagatedtooneormorecatchclauses.

    Here’sanexampleofhowerrorhandlingcanbeusedtorespondtodifferenterrorconditions:

    1 funcmakeASandwich()throws{

    2 //...

    3 }

    4

    5 do{

    6 trymakeASandwich()

    7 eatASandwich()

    8 }catchSandwichError.outOfCleanDishes{

    9 washDishes()

    }catchSandwichError.missingIngredients(letingredients){

    buyGroceries(ingredients)

    }

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

    Ifnoerroristhrown,theeatASandwich()functioniscalled.IfanerroristhrownanditmatchestheSandwichError.outOfCleanDishescase,thenthewashDishes()functionwillbecalled.IfanerroristhrownanditmatchestheSandwichError.missingIngredientscase,thenthebuyGroceries(_:)function

  • iscalledwiththeassociated[String]valuecapturedbythecatchpattern.

    Throwing,catching,andpropagatingerrorsiscoveredingreaterdetailinErrorHandling.

    Assertions

    Insomecases,itissimplynotpossibleforyourcodetocontinueexecutionifaparticularconditionisnotsatisfied.Inthesesituations,youcantriggeranassertioninyourcodetoendcodeexecutionandtoprovideanopportunitytodebugthecauseoftheabsentorinvalidvalue.

    DebuggingwithAssertions

    AnassertionisaruntimecheckthataBooleanconditiondefinitelyevaluatestotrue.Literallyput,anassertion“asserts”thataconditionistrue.Youuseanassertiontomakesurethatanessentialconditionissatisfiedbeforeexecutinganyfurthercode.Iftheconditionevaluatestotrue,codeexecutioncontinuesasusual;iftheconditionevaluatestofalse,codeexecutionends,andyourappisterminated.

    Ifyourcodetriggersanassertionwhilerunninginadebugenvironment,suchaswhenyoubuildandrunanappinXcode,youcanseeexactlywheretheinvalidstateoccurredandquerythestateofyourappatthetimethattheassertionwastriggered.Anassertionalsoletsyouprovideasuitabledebugmessageastothenatureoftheassert.

    YouwriteanassertionbycallingtheSwiftstandardlibraryglobalassert(_:_:file:line:)function.Youpassthisfunctionanexpressionthatevaluatestotrueorfalseandamessagethatshouldbedisplayediftheresultoftheconditionisfalse:

    1 letage=-3

    2 assert(age>=0,"Aperson'sagecannotbelessthanzero")

    3 //thiscausestheassertiontotrigger,becauseageisnot>=0

    Inthisexample,codeexecutionwillcontinueonlyifage>=0evaluatestotrue,thatis,ifthevalueofageisnon-negative.Ifthevalueofageisnegative,asinthecodeabove,thenage>=0evaluatestofalse,andtheassertionistriggered,terminatingtheapplication.

    Theassertionmessagecanbeomittedifdesired,asinthefollowingexample:

    assert(age>=0)

  • NOTE

    Assertionsaredisabledwhenyourcodeiscompiledwithoptimizations,suchaswhenbuildingwithanapptarget’sdefaultReleaseconfigurationinXcode.

    WhentoUseAssertions

    Useanassertionwheneveraconditionhasthepotentialtobefalse,butmustdefinitelybetrueinorderforyourcodetocontinueexecution.Suitablescenariosforanassertioncheckinclude:

    SeealsoSubscriptsandFunctions.

    NOTE

    Assertionscauseyourapptoterminateandarenotasubstitutefordesigningyourcodeinsuchawaythatinvalidconditionsareunlikelytoarise.Nonetheless,insituationswhereinvalidconditionsarepossible,anassertionisaneffectivewaytoensurethatsuchconditionsarehighlightedandnoticedduringdevelopment,beforeyourappispublished.

    Anintegersubscriptindexispassedtoacustomsubscriptimplementation,butthesubscriptindexvaluecouldbetoolowortoohigh.

    Avalueispassedtoafunction,butaninvalidvaluemeansthatthefunctioncannotfulfillitstask.

    Anoptionalvalueiscurrentlynil,butanon-nilvalueisessentialforsubsequentcodetoexecutesuccessfully.

  • BasicOperators

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

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

    Swiftalsoprovidestworangeoperators(a..

  • 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=ydoesnotreturnavalue.

    3 }

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

    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,theSwiftarithmeticoperatorsdonotallowvaluestooverflowbydefault.YoucanoptintovalueoverflowbehaviorbyusingSwift’soverflowoperators(suchasa&+b).SeeOverflowOperators.

    TheadditionoperatorisalsosupportedforStringconcatenation:

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

    RemainderOperator

    Theremainderoperator(a%b)worksouthowmanymultiplesofbwillfitinsideaandreturnsthevaluethatisleftover(knownastheremainder).

    NOTE

    Theremainderoperator(%)isalsoknownasamodulooperatorinotherlanguages.However,itsbehaviorinSwiftfornegativenumbersmeansthatitis,strictlyspeaking,aremainderratherthanamodulooperation.

    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.

    UnaryMinusOperator

    Thesignofanumericvaluecanbetoggledusingaprefixed-,knownastheunaryminusoperator:

    1 letthree=3

    2 letminusThree=-three//minusThreeequals-3

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

    Theunaryminusoperator(-)isprependeddirectlybeforethevalueitoperateson,withoutanywhitespace.

    UnaryPlusOperator

    Theunaryplusoperator(+)simplyreturnsthevalueitoperateson,withoutanychange:

    1 letminusSix=-6

    2 letalsoMinusSix=+minusSix//alsoMinusSixequals-6

    Althoughtheunaryplusoperatordoesn’tactuallydoanything,youcanuseittoprovidesymmetryinyourcodeforpositivenumberswhenalsousingtheunaryminusoperatorfornegativenumbers.

  • CompoundAssignmentOperators

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

    1 vara=1

    2 a+=2

    3 //aisnowequalto3

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

    NOTE

    Thecompoundassignmentoperatorsdonotreturnavalue.Forexample,youcannotwriteletb=a+=2.

    ForacompletelistofthecompoundassignmentoperatorsprovidedbytheSwiftstandardlibrary,seeSwiftStandardLibraryOperatorsReference.

    ComparisonOperators

    SwiftsupportsallstandardCcomparisonoperators:

    NOTE

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

    Equalto(a==b)•Notequalto(a!=b)•Greaterthan(a>b)•Lessthan(a<b)•Greaterthanorequalto(a>=b)•Lessthanorequalto(a

  • EachofthecomparisonoperatorsreturnsaBoolvaluetoindicatewhetherornotthestatementistrue:

    1 1==1//truebecause1isequalto1

    2 2!=1//truebecause2isnotequalto1

    3 2>1//truebecause2isgreaterthan1

    4 1<2//truebecause1islessthan2

    5 1>=1//truebecause1isgreaterthanorequalto1

    6 2

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

    arenotcompared

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

    than"bird"

    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.

    NOTE

    TheSwiftstandardlibraryincludestuplecomparisonoperatorsfortupleswithfewerthansevenelements.Tocomparetupleswithsevenormoreelements,youmustimplementthecomparisonoperatorsyourself.

    TernaryConditionalOperator

    Theternaryconditionaloperatorisaspecialoperatorwiththreeparts,whichtakestheformquestion?answer1:answer2.Itisashortcutforevaluatingoneoftwoexpressionsbasedonwhetherquestionistrueorfalse.Ifquestionistrue,itevaluatesanswer1andreturnsitsvalue;otherwise,itevaluatesanswer2andreturnsitsvalue.

    Theternaryconditionaloperatorisshorthandforthecodebelow:

    1 ifquestion{

    2 answer1

    3 }else{

    4 answer2

    5 }

    Here’sanexample,whichcalculatestheheightforatablerow.Therowheightshouldbe50pointstallerthanthecontentheightiftherowhasaheader,and20pointstalleriftherowdoesn’thavea

  • header:

    1 letcontentHeight=40

    2 lethasHeader=true

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

    4 //rowHeightisequalto90

    Theprecedingexampleisshorthandforthecodebelow:

    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,whichismoreconcisethanthecodeusedinthesecondexample.

    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

    4 varcolorNameToUse=userDefinedColorName??defaultColorName

    5 //userDefinedColorNameisnil,socolorNameToUseissettothedefaultof"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

    Swiftincludestworangeoperators,whichareshortcutsforexpressingarangeofvalues.

  • ClosedRangeOperator

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

    Theclosedrangeoperatorisusefulwheniteratingoverarangeinwhichyouwantallofthevaluestobeused,suchaswithafor-inloop:

    1 forindexin1...5{

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

    3 }

    4 //1times5is5

    5 //2times5is10

    6 //3times5is15

    7 //4times5is20

    8 //5times5is25

    Formoreonfor-inloops,seeControlFlow.

    Half-OpenRangeOperator

    Thehalf-openrangeoperator(a..

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

    2 letcount=names.count

    3 foriin0..

  • 1 letallowedEntry=false

    2 if!allowedEntry{

    3 print("ACCESSDENIED")

    4 }

    5 //Prints"ACCESSDENIED"

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

    Asinthisexample,carefulchoiceofBooleanconstantandvariablenamescanhelptokeepcodereadableandconcise,whileavoidingdoublenegativesorconfusinglogicstatements.

    LogicalANDOperator

    ThelogicalANDoperator(a&&b)createslogicalexpressionswherebothvaluesmustbetruefortheoverallexpressiontoalsobetrue.

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

    ThisexampleconsiderstwoBoolvaluesandonlyallowsaccessifbothvaluesaretrue:

    1 letenteredDoorCode=true

    2 letpassedRetinaScan=false

    3 ifenteredDoorCode&&passedRetinaScan{

    4 print("Welcome!")

    5 }else{

    6 print("ACCESSDENIED")

    7 }

    8 //Prints"ACCESSDENIED"

    LogicalOROperator

  • ThelogicalORoperator(a||b)isaninfixoperatormadefromtwoadjacentpipecharacters.Youuseittocreatelogicalexpressionsinwhichonlyoneofthetwovalueshastobetruefortheoverallexpressiontobetrue.

    LiketheLogicalANDoperatorabove,theLogicalORoperatorusesshort-circuitevaluationtoconsideritsexpressions.IftheleftsideofaLogicalORexpressionistrue,therightsideisnotevaluated,becauseitcannotchangetheoutcomeoftheoverallexpression.

    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!"

    CombiningLogicalOperators

    Youcancombinemultiplelogicaloperatorstocreatelongercompoundexpressions:

    1 ifenteredDoorCode&&passedRetinaScan||hasDoorKey||knowsOverridePassword{

    2 print("Welcome!")

    3 }else{

    4 print("ACCESSDENIED")

    5 }

    6 //Prints"Welcome!"

    Thisexampleusesmultiple&&and||operatorstocreatealongercompoundexpression.How