marek.piasecki.staff.iiar.pwr.wroc.plmarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/mc/L06/TheSwift... ·...

593
Welcome to Swift

Transcript of marek.piasecki.staff.iiar.pwr.wroc.plmarek.piasecki.staff.iiar.pwr.wroc.pl/dydaktyka/mc/L06/TheSwift... ·...

  • WelcometoSwift

  • AboutSwift

    SwiftisanewprogramminglanguageforiOS,OSX,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,OSX,watchOS,andtvOSapps,andwillcontinuetoevolvewithnewfeaturesandcapabilities.OurgoalsforSwiftareambitious.Wecan’twaittoseewhatyoucreatewithit.

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

  • 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

    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

    InstruktorXProstokąt

    InstruktorXProstokąt

  • 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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    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

    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

    InstruktorXProstokąt

    InstruktorXProstokąt

  • 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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

  • 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

    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

    InstruktorXProstokąt

    InstruktorXProstokąt

  • 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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

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

    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

    InstruktorXProstokąt

    InstruktorXProstokąt

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

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

    3 }

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

    EXPERIMEN T

    Removethedayparameter.Addaparametertoincludetoday’slunchspecialinthegreeting.

    Useatupletomakeacompoundvalue—forexample,toreturnmultiplevaluesfromafunction.Theelementsofatuplecanbereferredtoeitherbynameorbynumber.

    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

    InstruktorXProstokąt

  • 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([5,3,100,3,9])

    print(statistics.sum)

    print(statistics.2)

    Functionscanalsotakeavariablenumberofarguments,collectingthemintoanarray.

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

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

    2 varsum=0

    3 fornumberinnumbers{

    4 sum+=number

    5 }

    6 returnsum

    7 }

    8 sumOf()

    9 sumOf(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.

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

  • 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(numbers,condition:lessThanTen)

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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXProstokąt

    InstruktorXProstokąt

    InstruktorXProstokąt

  • 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.sort{$0>$1}

    2 print(sortedNumbers)

    ObjectsandClasses

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

    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

    InstruktorXProstokąt

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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    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.

    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.

    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

    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

  • 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

    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

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

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

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

    Usestructtocreateastructure.Structuressupportmanyofthesamebehaviorsasclasses,includingmethodsandinitializers.Oneofthemostimportantdifferencesbetweenstructuresandclassesisthatstructuresarealwayscopiedwhentheyarepassedaroundinyourcode,butclassesarepassedbyreference.

    InstruktorXWyróżnienie

    InstruktorXPodkreślenie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

    InstruktorXWyróżnienie

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

    Aninstanceofanenumerationcasecanhavevaluesassociatedwiththeinstance.Instancesofthesameenumerationcasecanhavedifferentvaluesassociatedwiththem.Youprovidetheassociatedvalueswhenyoucreatetheinstance.Associatedvaluesandrawvaluesaredifferent:Therawvalueofanenumerationcaseisthesameforallofitsinstances,andyouprovidetherawvaluewhenyoudefinetheenumeration.

    Forexample,considerthecaseofrequestingthesunriseandsunsettimefromaserver.Theservereitherrespondswiththeinformationoritrespondswithsomeerrorinformation.

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

    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

    YourepresenterrorsusinganytypethatadoptstheErrorTypeprotocol.

    1 enumPrinterError:ErrorType{

    2 caseOutOfPaper

    3 caseNoToner

    4 caseOnFire

    5 }

    Usethrowtothrowanerrorandthrowstomarkafunctionthatcanthrowanerror.Ifyouthrowanerrorinafunction,thefunctionreturnsimmediatelyandthecodethatcalledthefunctionhandlestheerror.

    1 funcsendToPrinter(printerName:String)throws->String{

    2 ifprinterName=="NeverHasToner"{

    3 throwPrinterError.NoToner

    4 }

    5 return"Jobsent"

    6 }

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

  • 1 do{

    2 letprinterResponse=trysendToPrinter("BiSheng")

    3 print(printerResponse)

    4 }catch{

    5 print(error)

    6 }

    EXPERIMEN T

    Changetheprinternameto"NeverHasToner",sothatthesendToPrinter(_:)functionthrowsanerror.

    Youcanprovidemultiplecatchblocksthathandlespecificerrors.Youwriteapatternaftercatchjustasyoudoaftercaseinaswitch.

    1 do{

    2 letprinterResponse=trysendToPrinter("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.Ifthefunctionthrows

  • anerror,thespecificerrorisdiscardedandtheresultisnil.Otherwise,theresultisanoptionalcontainingthevaluethatthefunctionreturned.

    1 letprinterSuccess=try?sendToPrinter("Mergenthaler")

    2 letprinterFailure=try?sendToPrinter("NeverHasToner")

    Usedefertowriteablockofcodethatisexecutedafterallothercodeinthefunction,justbeforethefunctionreturns.Thecodeisexecutedregardlessofwhetherthefunctionthrowsanerror.Youcanusedefertowritesetupandcleanupcodenexttoeachother,eventhoughtheyneedtobeexecutedatdifferenttimes.

    1 varfridgeIsOpen=false

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

    3

    4 funcfridgeContains(itemName:String)->Bool{

    5 fridgeIsOpen=true

    6 defer{

    7 fridgeIsOpen=false

    8 }

    9

    letresult=fridgeContent.contains(itemName)

    returnresult

    }

    fridgeContains("banana")

    print(fridgeIsOpen)

    Generics

    Writeanameinsideanglebracketstomakeagenericfunctionortype.

  • 1 funcrepeatItem(item:Item,numberOfTimes:Int)->[Item]{

    2 varresult=[Item]()

    3 for_in0..

  • 1 funcanyCommonElements(lhs:T,_rhs:U)-

    >Bool{

    2 forlhsIteminlhs{

    3 forrhsIteminrhs{

    4 iflhsItem==rhsItem{

    5 returntrue

    6 }

    7 }

    8 }

    9 returnfalse

    }

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

    EXPERIMEN T

    ModifytheanyCommonElements(_:_:)functiontomakeafunctionthatreturnsanarrayoftheelementsthatanytwosequenceshaveincommon.

    Writingisthesameaswriting.

  • LanguageGuide

  • TheBasics

    SwiftisanewprogramminglanguageforiOS,OSX,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 butwrittenovermultiplelines*/

    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.Anoptionalsays:

    or

    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"

    Thereisavalue,anditequalsx•

    Thereisn’tavalueatall•

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

    YoucanincludemultipleoptionalbindingsinasingleifstatementanduseawhereclausetocheckforaBooleancondition.Ifanyofthevaluesintheoptionalbindingsarenilorthewhereclauseevaluatestofalse,thewholeoptionalbindingisconsideredunsuccessful.

    1 ifletfirstNumber=Int("4"),secondNumber=Int("42")wherefirstNumber<

    secondNumber{

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

    3 }

    4 //Prints"4<42"

  • NOTE

    Constantsandvariablescreatedwithoptionalbindinginanifstatement.areavailableonlywithinthebodyoftheifstatement.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’scallercanthen

  • catchtheerrorandrespondappropriately.

    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 }catchError.OutOfCleanDishes{

    9 washDishes()

    }catchError.MissingIngredients(letingredients){

    buyGroceries(ingredients)

    }

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

    Ifnoerroristhrown,theeatASandwich()functioniscalled.IfanerroristhrownanditmatchestheError.OutOfCleanDishescase,thenthewashDishes()functionwillbecalled.IfanerroristhrownanditmatchestheError.MissingIngredientscase,thenthebuyGroceries(_:)functioniscalledwiththeassociated[String]valuecapturedbythecatchpattern.

    Throwing,catching,andpropagatingerrorsiscoveredingreaterdetailinErrorHandling.

    Assertions

    Insomecases,itissimplynotpossibleforyourcodetocontinueexecutionifaparticularconditionisnotsatisfied.Inthesesituations,youcantriggeranassertioninyourcodetoendcodeexecutionandtoprovideanopportunitytodebugthecauseoftheabsentorinvalidvalue.

    DebuggingwithAssertions

    AnassertionisaruntimecheckthataBooleanconditiondefinitelyevaluatestotrue.Literallyput,an

  • assertion“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:

    Anintegersubscriptindexispassedtoacustomsubscriptimplementation,butthesubscriptindexvaluecouldbetoolowortoohigh.

    Avalueispassedtoafunction,butaninvalidvaluemeansthatthefunctioncannotfulfillitstask.

  • SeealsoSubscriptsandFunctions.

    NOTE

    Assertionscauseyourapptoterminateandarenotasubstitutefordesigningyourcodeinsuchawaythatinvalidconditionsareunlikelytoarise.Nonetheless,insituationswhereinvalidconditionsarepossible,anassertionisaneffectivewaytoensurethatsuchconditionsarehighlightedandnoticedduringdevelopment,beforeyourappispublished.

    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.

    UnlikeC,Swiftletsyouperformremainder(%)calculationsonfloating-pointnumbers.Swiftalsoprovidestworangeoperators(a..

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

    Floating-PointRemainderCalculations

    UnliketheremainderoperatorinCandObjective-C,Swift’sremainderoperatorcanalsooperateonfloating-pointnumbers:

    8%2.5//equals0.5

    Inthisexample,8dividedby2.5equals3,witharemainderof0.5,sotheremainderoperatorreturnsaDoublevalueof0.5.

    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.

    AcompletelistofcompoundassignmentoperatorscanbefoundinExpressions.

  • ComparisonOperators

    SwiftsupportsallstandardCcomparisonoperators:

    NOTE

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

    EachofthecomparisonoperatorsreturnsaBoolvaluetoindicatewhetherornotthestatementistrue:

    1 1==1//truebecause1isequalto1

    2 2!=1//truebecause2isnotequalto1

    3 2>1//truebecause2isgreaterthan1

    4 1<2//truebecause1islessthan2

    5 1>=1//truebecause1isgreaterthanorequalto1

    6 2b)•Lessthan(a<b)•Greaterthanorequalto(a>=b)•Lessthanorequalto(a

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

    Formoreontheifstatement,seeControlFlow.

    Youcanalsocomparetuplesthathavethesamenumberofvalues,aslongaseachofthevaluesinthetuplecanbecompared.Forexample,bothIntandStringcanbecompared,whichmeanstuplesofthetype(Int,String)canbecompared.Incontrast,Boolcan’tbecompared,whichmeanstuplesthatcontainaBooleanvaluecan’tbecompared.

    Tuplesarecomparedfromlefttoright,onevalueatatime,untilthecomparisonfindstwovaluesthataren’tequal.Ifalltheelementsareequal,thenthetuplesthemselvesareequal.Forexample:

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

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

    than"bird"

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

    to"dog"

    NOTE

    TheSwiftstandardlibraryincludestuplecomparisonoperatorsfortupleswithlessthansevenelements.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’thaveaheader:

    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.Thisismoreconcisethanthesecondexample,andremovestheneedforrowHeighttobeavariable,becauseitsvaluedoesnotneedtobemodifiedwithinanifstatement.

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

    NilCoalescingOperator

    Thenilcoalescingoperator(a??b)unwrapsanoptionalaifitcontainsavalue,orreturnsadefaultvaluebifaisnil.Theexpressionaisalwaysofanoptionaltype.Theexpressionbmustmatchthetypethatisstoredinsidea.

    Thenilcoalescingoperatorisshorthandforthecodebelow:

    a!=nil?a!:b

    Thecodeaboveusestheternaryconditionaloperatorandforcedunwrapping(a!)toaccessthevaluewrappedinsideawhenaisnotnil,andtoreturnbotherwise.Thenilcoalescingoperatorprovidesamoreelegantwaytoencapsulatethisconditionalcheckingandunwrappinginaconciseandreadableform.

    NOTE

    Ifthevalueofaisnon-nil,thevalueofbisnotevaluated.Thisisknownasshort-circuitevaluation.

    Theexamplebelowusesthenilcoalescingoperatortochoosebetweenadefaultcolornameandanoptionaluser-definedcolorname:

    1 letdefaultColorName="red"

    2 varuserDefinedColorName:String?//defaultstonil

    3

    4 varcolorNameToUse=userDefinedColorName??defaultColorName

    5 //userDefinedColorNameisnil,socolorNameToUseissettothedefaultof"red"

    TheuserDefinedColorNamevariableisdefinedasanoptionalString,withadefaultvalueofnil.BecauseuserDefinedColorNameisofanoptionaltype,youcanusethenilcoalescingoperatortoconsideritsvalue.Intheexampleabove,theoperatorisusedtodetermineaninitialvalueforaStringvariablecalledcolorNameToUse.BecauseuserDefinedColorNameisnil,theexpressionuserDefinedColorName??defaultColorNamereturnsthevalueofdefaultColorName,or"red".

  • Ifyouassignanon-nilvaluetouserDefinedColorNameandperformthenilcoalescingoperatorcheckagain,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..

  • saidtobehalf-openbecauseitcontainsitsfirstvalue,butnotitsfinalvalue.Aswiththeclosedrangeoperator,thevalueofamustnotbegreaterthanb.Ifthevalueofaisequaltob,thentheresultingrangewillbeempty.

    Half-openrangesareparticularlyusefulwhenyouworkwithzero-basedlistssuchasarrays,whereitisusefultocountupto(butnotincluding)thelengthofthelist:

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

    2 letcount=names.count

    3 foriin0..

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

    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.However,the&&and||operatorsstilloperateononlytwovalues,sothisisactuallythreesmallerexpressionschainedtogether.Theexamplecanbereadas:

    Ifwe’veenteredthecorrectdoorcodeandpassedtheretinascan,orifwehaveavaliddoorkey,orifweknowtheemergencyoverridepassword,thenallowaccess.

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

    NOTE

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

    ExplicitParentheses

    Itissometimesusefultoincludeparentheseswhentheyarenotstrictlyneeded,tomaketheintentionofacomplexexpressioneasiertoread.Inthedooraccessexampleabove,itisusefultoaddparenthesesaroundthefirstpartofthecompoundexpressiontomakeitsintentexplicit:

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

    2 print("Welcome!")

    3 }else{

    4 print("ACCESSDENIED")

    5 }

    6 //Prints"Welcome!"

    Theparenthesesmakeitclearthatthefirsttwovaluesareconsideredaspartofaseparatepossiblestateintheoveralllogic.Theoutputofthecompoundexpressiondoesn’tcha