Upload
others
View
16
Download
0
Embed Size (px)
Citation preview
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