Welcome to Swift - autonom.iiar.pwr.wroc.pl · About Swift Swift is a new programming language for...
Transcript of Welcome to Swift - autonom.iiar.pwr.wroc.pl · About Swift Swift is a new programming language for...
-
WelcometoSwift
-
AboutSwift
SwiftisanewprogramminglanguageforiOS,macOS,watchOS,andtvOSappsthatbuildsonthebestofCandObjective-C,withouttheconstraintsofCcompatibility.Swiftadoptssafeprogrammingpatternsandaddsmodernfeaturestomakeprogrammingeasier,moreflexible,andmorefun.Swift’scleanslate,backedbythematureandmuch-lovedCocoaandCocoaTouchframeworks,isanopportunitytoreimaginehowsoftwaredevelopmentworks.
Swifthasbeenyearsinthemaking.ApplelaidthefoundationforSwiftbyadvancingourexistingcompiler,debugger,andframeworkinfrastructure.WesimplifiedmemorymanagementwithAutomaticReferenceCounting(ARC).Ourframeworkstack,builtonthesolidbaseofFoundationandCocoa,hasbeenmodernizedandstandardizedthroughout.Objective-Citselfhasevolvedtosupportblocks,collectionliterals,andmodules,enablingframeworkadoptionofmodernlanguagetechnologieswithoutdisruption.Thankstothisgroundwork,wecannowintroduceanewlanguageforthefutureofApplesoftwaredevelopment.
SwiftfeelsfamiliartoObjective-Cdevelopers.ItadoptsthereadabilityofObjective-C’snamedparametersandthepowerofObjective-C’sdynamicobjectmodel.ItprovidesseamlessaccesstoexistingCocoaframeworksandmix-and-matchinteroperabilitywithObjective-Ccode.Buildingfromthiscommonground,Swiftintroducesmanynewfeaturesandunifiestheproceduralandobject-orientedportionsofthelanguage.
Swiftisfriendlytonewprogrammers.Itisthefirstindustrial-qualitysystemsprogramminglanguagethatisasexpressiveandenjoyableasascriptinglanguage.Itsupportsplaygrounds,aninnovativefeaturethatallowsprogrammerstoexperimentwithSwiftcodeandseetheresultsimmediately,withouttheoverheadofbuildingandrunninganapp.
SwiftcombinesthebestinmodernlanguagethinkingwithwisdomfromthewiderAppleengineeringculture.Thecompilerisoptimizedforperformance,andthelanguageisoptimizedfordevelopment,withoutcompromisingoneither.It’sdesignedtoscalefrom“hello,world”toanentireoperatingsystem.AllthismakesSwiftasoundfutureinvestmentfordevelopersandforApple.
SwiftisafantasticwaytowriteiOS,macOS,watchOS,andtvOSapps,andwillcontinuetoevolvewithnewfeaturesandcapabilities.OurgoalsforSwiftareambitious.Wecan’twaittoseewhatyoucreatewithit.
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
ASwiftTour
Traditionsuggeststhatthefirstprograminanewlanguageshouldprintthewords“Hello,world!”onthescreen.InSwift,thiscanbedoneinasingleline:
print("Hello,world!")
IfyouhavewrittencodeinCorObjective-C,thissyntaxlooksfamiliartoyou—inSwift,thislineofcodeisacompleteprogram.Youdon’tneedtoimportaseparatelibraryforfunctionalitylikeinput/outputorstringhandling.Codewrittenatglobalscopeisusedastheentrypointfortheprogram,soyoudon’tneedamain()function.Youalsodon’tneedtowritesemicolonsattheendofeverystatement.
ThistourgivesyouenoughinformationtostartwritingcodeinSwiftbyshowingyouhowtoaccomplishavarietyofprogrammingtasks.Don’tworryifyoudon’tunderstandsomething—everythingintroducedinthistourisexplainedindetailintherestofthisbook.
NOTE
OnaMac,downloadthePlaygroundanddouble-clickthefiletoopenitinXcode:https://developer.apple.com/go/?id=swift-tour
SimpleValues
Uselettomakeaconstantandvartomakeavariable.Thevalueofaconstantdoesn’tneedtobeknownatcompiletime,butyoumustassignitavalueexactlyonce.Thismeansyoucanuseconstantstonameavaluethatyoudetermineoncebutuseinmanyplaces.
1 varmyVariable=42
2 myVariable=50
3 letmyConstant=42
Aconstantorvariablemusthavethesametypeasthevalueyouwanttoassigntoit.However,youdon’talwayshavetowritethetypeexplicitly.Providingavaluewhenyoucreateaconstantorvariableletsthecompilerinferitstype.Intheexampleabove,thecompilerinfersthatmyVariableisanintegerbecauseitsinitialvalueisaninteger.
https://developer.apple.com/go/?id=swift-tourInstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
Iftheinitialvaluedoesn’tprovideenoughinformation(orifthereisnoinitialvalue),specifythetypebywritingitafterthevariable,separatedbyacolon.
1 letimplicitInteger=70
2 letimplicitDouble=70.0
3 letexplicitDouble:Double=70
EXPERIMEN T
CreateaconstantwithanexplicittypeofFloatandavalueof4.
Valuesareneverimplicitlyconvertedtoanothertype.Ifyouneedtoconvertavaluetoadifferenttype,explicitlymakeaninstanceofthedesiredtype.
1 letlabel="Thewidthis"
2 letwidth=94
3 letwidthLabel=label+String(width)
EXPERIMEN T
TryremovingtheconversiontoStringfromthelastline.Whaterrordoyouget?
There’sanevensimplerwaytoincludevaluesinstrings:Writethevalueinparentheses,andwriteabackslash(\)beforetheparentheses.Forexample:
1 letapples=3
2 letoranges=5
3 letappleSummary="Ihave\(apples)apples."
4 letfruitSummary="Ihave\(apples+oranges)piecesoffruit."
EXPERIMEN T
Use\()toincludeafloating-pointcalculationinastringandtoincludesomeone’snameinagreeting.
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
-
Createarraysanddictionariesusingbrackets([]),andaccesstheirelementsbywritingtheindexorkeyinbrackets.Acommaisallowedafterthelastelement.
1 varshoppingList=["catfish","water","tulips","bluepaint"]
2 shoppingList[1]="bottleofwater"
3
4 varoccupations=[
5 "Malcolm":"Captain",
6 "Kaylee":"Mechanic",
7 ]
8 occupations["Jayne"]="PublicRelations"
Tocreateanemptyarrayordictionary,usetheinitializersyntax.
1 letemptyArray=[String]()
2 letemptyDictionary=[String:Float]()
Iftypeinformationcanbeinferred,youcanwriteanemptyarrayas[]andanemptydictionaryas[:]—forexample,whenyousetanewvalueforavariableorpassanargumenttoafunction.
1 shoppingList=[]
2 occupations=[:]
ControlFlow
Useifandswitchtomakeconditionals,andusefor-in,for,while,andrepeat-whiletomakeloops.Parenthesesaroundtheconditionorloopvariableareoptional.Bracesaroundthebodyarerequired.
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 letindividualScores=[75,43,103,87,12]
2 varteamScore=0
3 forscoreinindividualScores{
4 ifscore>50{
5 teamScore+=3
6 }else{
7 teamScore+=1
8 }
9 }
print(teamScore)
Inanifstatement,theconditionalmustbeaBooleanexpression—thismeansthatcodesuchasifscore{...}isanerror,notanimplicitcomparisontozero.
Youcanuseifandlettogethertoworkwithvaluesthatmightbemissing.Thesevaluesarerepresentedasoptionals.Anoptionalvalueeithercontainsavalueorcontainsniltoindicatethatavalueismissing.Writeaquestionmark(?)afterthetypeofavaluetomarkthevalueasoptional.
1 varoptionalString:String?="Hello"
2 print(optionalString==nil)
3
4 varoptionalName:String?="JohnAppleseed"
5 vargreeting="Hello!"
6 ifletname=optionalName{
7 greeting="Hello,\(name)"
8 }
EXPERIMEN T
ChangeoptionalNametonil.Whatgreetingdoyouget?AddanelseclausethatsetsadifferentgreetingifoptionalNameisnil.
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
Iftheoptionalvalueisnil,theconditionalisfalseandthecodeinbracesisskipped.Otherwise,theoptionalvalueisunwrappedandassignedtotheconstantafterlet,whichmakestheunwrappedvalueavailableinsidetheblockofcode.
Anotherwaytohandleoptionalvaluesistoprovideadefaultvalueusingthe??operator.Iftheoptionalvalueismissing,thedefaultvalueisusedinstead.
1 letnickName:String?=nil
2 letfullName:String="JohnAppleseed"
3 letinformalGreeting="Hi\(nickName??fullName)"
Switchessupportanykindofdataandawidevarietyofcomparisonoperations—theyaren’tlimitedtointegersandtestsforequality.
1 letvegetable="redpepper"
2 switchvegetable{
3 case"celery":
4 print("Addsomeraisinsandmakeantsonalog.")
5 case"cucumber","watercress":
6 print("Thatwouldmakeagoodteasandwich.")
7 caseletxwherex.hasSuffix("pepper"):
8 print("Isitaspicy\(x)?")
9 default:
print("Everythingtastesgoodinsoup.")
}
EXPERIMEN T
Tryremovingthedefaultcase.Whaterrordoyouget?
Noticehowletcanbeusedinapatterntoassignthevaluethatmatchedthepatterntoaconstant.
Afterexecutingthecodeinsidetheswitchcasethatmatched,theprogramexitsfromtheswitchstatement.Executiondoesn’tcontinuetothenextcase,sothereisnoneedtoexplicitlybreakoutoftheswitchattheendofeachcase’scode.
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
Youusefor-intoiterateoveritemsinadictionarybyprovidingapairofnamestouseforeachkey-valuepair.Dictionariesareanunorderedcollection,sotheirkeysandvaluesareiteratedoverinanarbitraryorder.
1 letinterestingNumbers=[
2 "Prime":[2,3,5,7,11,13],
3 "Fibonacci":[1,1,2,3,5,8],
4 "Square":[1,4,9,16,25],
5 ]
6 varlargest=0
7 for(kind,numbers)ininterestingNumbers{
8 fornumberinnumbers{
9 ifnumber>largest{
largest=number
}
}
}
print(largest)
EXPERIMEN T
Addanothervariabletokeeptrackofwhichkindofnumberwasthelargest,aswellaswhatthatlargestnumberwas.
Usewhiletorepeatablockofcodeuntilaconditionchanges.Theconditionofaloopcanbeattheendinstead,ensuringthattheloopisrunatleastonce.
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 varn=2
2 whilen<100{
3 n=n*2
4 }
5 print(n)
6
7 varm=2
8 repeat{
9 m=m*2
}whilem<100
print(m)
Youcankeepanindexinaloopbyusing..<tomakearangeofindexes.
1 vartotal=0
2 foriin0..toseparatetheparameternamesandtypesfromthefunction’sreturntype.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 funcgreet(person:String,day:String)->String{
2 return"Hello\(person),todayis\(day)."
3 }
4 greet(person:"Bob",day:"Tuesday")
EXPERIMEN T
Removethedayparameter.Addaparametertoincludetoday’slunchspecialinthegreeting.
Bydefault,functionsusetheirparameternamesaslabelsfortheirarguments.Writeacustomargumentlabelbeforetheparametername,orwrite_tousenoargumentlabel.
1 funcgreet(_person:String,onday:String)->String{
2 return"Hello\(person),todayis\(day)."
3 }
4 greet("John",on:"Wednesday")
Useatupletomakeacompoundvalue—forexample,toreturnmultiplevaluesfromafunction.Theelementsofatuplecanbereferredtoeitherbynameorbynumber.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXPodkreślenie
InstruktorXPodkreślenie
InstruktorXPodkreślenie
InstruktorXPodkreślenie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXPodkreślenie
InstruktorXPodkreślenie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 funccalculateStatistics(scores:[Int])->(min:Int,max:Int,sum:Int){
2 varmin=scores[0]
3 varmax=scores[0]
4 varsum=0
5
6 forscoreinscores{
7 ifscore>max{
8 max=score
9 }elseifscore<min{
min=score
}
sum+=score
}
return(min,max,sum)
}
letstatistics=calculateStatistics(scores:[5,3,100,3,9])
print(statistics.sum)
print(statistics.2)
Functionscanalsotakeavariablenumberofarguments,collectingthemintoanarray.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXPodkreślenie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXPodkreślenie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 funcsumOf(numbers:Int...)->Int{
2 varsum=0
3 fornumberinnumbers{
4 sum+=number
5 }
6 returnsum
7 }
8 sumOf()
9 sumOf(numbers:42,597,12)
EXPERIMEN T
Writeafunctionthatcalculatestheaverageofitsarguments.
Functionscanbenested.Nestedfunctionshaveaccesstovariablesthatweredeclaredintheouterfunction.Youcanusenestedfunctionstoorganizethecodeinafunctionthatislongorcomplex.
1 funcreturnFifteen()->Int{
2 vary=10
3 funcadd(){
4 y+=5
5 }
6 add()
7 returny
8 }
9 returnFifteen()
Functionsareafirst-classtype.Thismeansthatafunctioncanreturnanotherfunctionasitsvalue.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 funcmakeIncrementer()->((Int)->Int){
2 funcaddOne(number:Int)->Int{
3 return1+number
4 }
5 returnaddOne
6 }
7 varincrement=makeIncrementer()
8 increment(7)
Afunctioncantakeanotherfunctionasoneofitsarguments.
1 funchasAnyMatches(list:[Int],condition:(Int)->Bool)->Bool{
2 foriteminlist{
3 ifcondition(item){
4 returntrue
5 }
6 }
7 returnfalse
8 }
9 funclessThanTen(number:Int)->Bool{
returnnumber<10
}
varnumbers=[20,19,7,12]
hasAnyMatches(list:numbers,condition:lessThanTen)
Functionsareactuallyaspecialcaseofclosures:blocksofcodethatcanbecalledlater.Thecodeinaclosurehasaccesstothingslikevariablesandfunctionsthatwereavailableinthescopewheretheclosurewascreated,eveniftheclosureisinadifferentscopewhenitisexecuted—yousawanexampleofthisalreadywithnestedfunctions.Youcanwriteaclosurewithoutanamebysurroundingcodewithbraces({}).Useintoseparatetheargumentsandreturntypefromthebody.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXPodkreślenie
InstruktorXPodkreślenie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 numbers.map({
2 (number:Int)->Intin
3 letresult=3*number
4 returnresult
5 })
EXPERIMEN T
Rewritetheclosuretoreturnzeroforalloddnumbers.
Youhaveseveraloptionsforwritingclosuresmoreconcisely.Whenaclosure’stypeisalreadyknown,suchasthecallbackforadelegate,youcanomitthetypeofitsparameters,itsreturntype,orboth.Singlestatementclosuresimplicitlyreturnthevalueoftheironlystatement.
1 letmappedNumbers=numbers.map({numberin3*number})
2 print(mappedNumbers)
Youcanrefertoparametersbynumberinsteadofbyname—thisapproachisespeciallyusefulinveryshortclosures.Aclosurepassedasthelastargumenttoafunctioncanappearimmediatelyaftertheparentheses.Whenaclosureistheonlyargumenttoafunction,youcanomittheparenthesesentirely.
1 letsortedNumbers=numbers.sorted{$0>$1}
2 print(sortedNumbers)
ObjectsandClasses
Useclassfollowedbytheclass’snametocreateaclass.Apropertydeclarationinaclassiswrittenthesamewayasaconstantorvariabledeclaration,exceptthatitisinthecontextofaclass.Likewise,methodandfunctiondeclarationsarewrittenthesameway.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXPodkreślenie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 classShape{
2 varnumberOfSides=0
3 funcsimpleDescription()->String{
4 return"Ashapewith\(numberOfSides)sides."
5 }
6 }
EXPERIMEN T
Addaconstantpropertywithlet,andaddanothermethodthattakesanargument.
Createaninstanceofaclassbyputtingparenthesesaftertheclassname.Usedotsyntaxtoaccessthepropertiesandmethodsoftheinstance.
1 varshape=Shape()
2 shape.numberOfSides=7
3 varshapeDescription=shape.simpleDescription()
ThisversionoftheShapeclassismissingsomethingimportant:aninitializertosetuptheclasswhenaninstanceiscreated.Useinittocreateone.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXPodkreślenie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 classNamedShape{
2 varnumberOfSides:Int=0
3 varname:String
4
5 init(name:String){
6 self.name=name
7 }
8
9 funcsimpleDescription()->String{
return"Ashapewith\(numberOfSides)sides."
}
}
Noticehowselfisusedtodistinguishthenamepropertyfromthenameargumenttotheinitializer.Theargumentstotheinitializerarepassedlikeafunctioncallwhenyoucreateaninstanceoftheclass.Everypropertyneedsavalueassigned—eitherinitsdeclaration(aswithnumberOfSides)orintheinitializer(aswithname).
Usedeinittocreateadeinitializerifyouneedtoperformsomecleanupbeforetheobjectisdeallocated.
Subclassesincludetheirsuperclassnameaftertheirclassname,separatedbyacolon.Thereisnorequirementforclassestosubclassanystandardrootclass,soyoucanincludeoromitasuperclassasneeded.
Methodsonasubclassthatoverridethesuperclass’simplementationaremarkedwithoverride—overridingamethodbyaccident,withoutoverride,isdetectedbythecompilerasanerror.Thecompileralsodetectsmethodswithoverridethatdon’tactuallyoverrideanymethodinthesuperclass.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 classSquare:NamedShape{
2 varsideLength:Double
3
4 init(sideLength:Double,name:String){
5 self.sideLength=sideLength
6 super.init(name:name)
7 numberOfSides=4
8 }
9
funcarea()->Double{
returnsideLength*sideLength
}
overridefuncsimpleDescription()->String{
return"Asquarewithsidesoflength\(sideLength)."
}
}
lettest=Square(sideLength:5.2,name:"mytestsquare")
test.area()
test.simpleDescription()
EXPERIMEN T
MakeanothersubclassofNamedShapecalledCirclethattakesaradiusandanameasargumentstoitsinitializer.Implementanarea()andasimpleDescription()methodontheCircleclass.
Inadditiontosimplepropertiesthatarestored,propertiescanhaveagetterandasetter.
InstruktorXProstokąt
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 classEquilateralTriangle:NamedShape{
2 varsideLength:Double=0.0
3
4 init(sideLength:Double,name:String){
5 self.sideLength=sideLength
6 super.init(name:name)
7 numberOfSides=3
8 }
9
varperimeter:Double{
get{
return3.0*sideLength
}
set{
sideLength=newValue/3.0
}
}
overridefuncsimpleDescription()->String{
return"Anequilateraltrianglewithsidesoflength\(sideLength)."
}
}
vartriangle=EquilateralTriangle(sideLength:3.1,name:"atriangle")
print(triangle.perimeter)
triangle.perimeter=9.9
print(triangle.sideLength)
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
Inthesetterforperimeter,thenewvaluehastheimplicitnamenewValue.Youcanprovideanexplicitnameinparenthesesafterset.
NoticethattheinitializerfortheEquilateralTriangleclasshasthreedifferentsteps:
1. Settingthevalueofpropertiesthatthesubclassdeclares.2. Callingthesuperclass’sinitializer.3. Changingthevalueofpropertiesdefinedbythesuperclass.Anyadditionalsetupworkthatuses
methods,getters,orsetterscanalsobedoneatthispoint.
Ifyoudon’tneedtocomputethepropertybutstillneedtoprovidecodethatisrunbeforeandaftersettinganewvalue,usewillSetanddidSet.Thecodeyouprovideisrunanytimethevaluechangesoutsideofaninitializer.Forexample,theclassbelowensuresthatthesidelengthofitstriangleisalwaysthesameasthesidelengthofitssquare.
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
1 classTriangleAndSquare{
2 vartriangle:EquilateralTriangle{
3 willSet{
4 square.sideLength=newValue.sideLength
5 }
6 }
7 varsquare:Square{
8 willSet{
9 triangle.sideLength=newValue.sideLength
}
}
init(size:Double,name:String){
square=Square(sideLength:size,name:name)
triangle=EquilateralTriangle(sideLength:size,name:name)
}
}
vartriangleAndSquare=TriangleAndSquare(size:10,name:"anothertestshape")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square=Square(sideLength:50,name:"largersquare")
print(triangleAndSquare.triangle.sideLength)
Whenworkingwithoptionalvalues,youcanwrite?beforeoperationslikemethods,properties,andsubscripting.Ifthevaluebeforethe?isnil,everythingafterthe?isignoredandthevalueofthewholeexpressionisnil.Otherwise,theoptionalvalueisunwrapped,andeverythingafterthe?actsontheunwrappedvalue.Inbothcases,thevalueofthewholeexpressionisanoptionalvalue.
1 letoptionalSquare:Square?=Square(sideLength:2.5,name:"optionalsquare")
2 letsideLength=optionalSquare?.sideLength
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
InstruktorXWyróżnienie
-
EnumerationsandStructures
Useenumtocreateanenumeration.Likeclassesandallothernamedtypes,enumerationscanhavemethodsassociatedwiththem.
1 enumRank:Int{
2 caseace=1
3 casetwo,three,four,five,six,seven,eight,nine,ten
4 casejack,queen,king
5 funcsimpleDescription()->String{
6 switchself{
7 case.ace:
8 return"ace"
9 case.jack:
return"jack"
case.queen:
return"queen"
case.king:
return"king"
default:
returnString(self.rawValue)
}
}
}
letace=Rank.ace
letaceRawValue=ace.rawValue
-
EXPERIMEN T
WriteafunctionthatcomparestwoRankvaluesbycomparingtheirrawvalues.
Bydefault,Swiftassignstherawvaluesstartingatzeroandincrementingbyoneeachtime,butyoucanchangethisbehaviorbyexplicitlyspecifyingvalues.Intheexampleabove,Aceisexplicitlygivenarawvalueof1,andtherestoftherawvaluesareassignedinorder.Youcanalsousestringsorfloating-pointnumbersastherawtypeofanenumeration.UsetherawValuepropertytoaccesstherawvalueofanenumerationcase.
Usetheinit?(rawValue:)initializertomakeaninstanceofanenumerationfromarawvalue.
1 ifletconvertedRank=Rank(rawValue:3){
2 letthreeDescription=convertedRank.simpleDescription()
3 }
Thecasevaluesofanenumerationareactualvalues,notjustanotherwayofwritingtheirrawvalues.Infact,incaseswherethereisn’tameaningfulrawvalue,youdon’thavetoprovideone.
-
1 enumSuit{
2 casespades,hearts,diamonds,clubs
3 funcsimpleDescription()->String{
4 switchself{
5 case.spades:
6 return"spades"
7 case.hearts:
8 return"hearts"
9 case.diamonds:
return"diamonds"
case.clubs:
return"clubs"
}
}
}
lethearts=Suit.hearts
letheartsDescription=hearts.simpleDescription()
EXPERIMEN T
Addacolor()methodtoSuitthatreturns“black”forspadesandclubs,andreturns“red”forheartsanddiamonds.
Noticethetwowaysthattheheartscaseoftheenumerationisreferredtoabove:Whenassigningavaluetotheheartsconstant,theenumerationcaseSuit.heartsisreferredtobyitsfullnamebecausetheconstantdoesn’thaveanexplicittypespecified.Insidetheswitch,theenumerationcaseisreferredtobytheabbreviatedform.heartsbecausethevalueofselfisalreadyknowntobeasuit.Youcanusetheabbreviatedformanytimethevalue’stypeisalreadyknown.
Ifanenumerationhasrawvalues,thosevaluesaredeterminedaspartofthedeclaration,whichmeanseveryinstanceofaparticularenumerationcasealwayshasthesamerawvalue.Anotherchoiceforenumerationcasesistohavevaluesassociatedwiththecase—thesevaluesaredeterminedwhenyoumaketheinstance,andtheycanbedifferentforeachinstanceofanenumerationcase.Youcanthink
-
oftheassociatedvaluesasbehavinglikestoredpropertiesoftheenumerationcaseinstance.Forexample,considerthecaseofrequestingthesunriseandsunsettimesfromaserver.Theservereitherrespondswiththerequestedinformation,oritrespondswithadescriptionofwhatwentwrong.
1 enumServerResponse{
2 caseresult(String,String)
3 casefailure(String)
4 }
5
6 letsuccess=ServerResponse.result("6:00am","8:09pm")
7 letfailure=ServerResponse.failure("Outofcheese.")
8
9 switchsuccess{
caselet.result(sunrise,sunset):
print("Sunriseisat\(sunrise)andsunsetisat\(sunset).")
caselet.failure(message):
print("Failure...\(message)")
}
EXPERIMEN T
AddathirdcasetoServerResponseandtotheswitch.
NoticehowthesunriseandsunsettimesareextractedfromtheServerResponsevalueaspartofmatchingthevalueagainsttheswitchcases.
Usestructtocreateastructure.Structuressupportmanyofthesamebehaviorsasclasses,includingmethodsandinitializers.Oneofthemostimportantdifferencesbetweenstructuresandclassesisthatstructuresarealwayscopiedwhentheyarepassedaroundinyourcode,butclassesarepassedbyreference.
-
1 structCard{
2 varrank:Rank
3 varsuit:Suit
4 funcsimpleDescription()->String{
5 return"The\(rank.simpleDescription())of\(suit.simpleDescription())"
6 }
7 }
8 letthreeOfSpades=Card(rank:.three,suit:.spades)
9 letthreeOfSpadesDescription=threeOfSpades.simpleDescription()
EXPERIMEN T
AddamethodtoCardthatcreatesafulldeckofcards,withonecardofeachcombinationofrankandsuit.
ProtocolsandExtensions
Useprotocoltodeclareaprotocol.
1 protocolExampleProtocol{
2 varsimpleDescription:String{get}
3 mutatingfuncadjust()
4 }
Classes,enumerations,andstructscanalladoptprotocols.
-
1 classSimpleClass:ExampleProtocol{
2 varsimpleDescription:String="Averysimpleclass."
3 varanotherProperty:Int=69105
4 funcadjust(){
5 simpleDescription+="Now100%adjusted."
6 }
7 }
8 vara=SimpleClass()
9 a.adjust()
letaDescription=a.simpleDescription
structSimpleStructure:ExampleProtocol{
varsimpleDescription:String="Asimplestructure"
mutatingfuncadjust(){
simpleDescription+="(adjusted)"
}
}
varb=SimpleStructure()
b.adjust()
letbDescription=b.simpleDescription
EXPERIMEN T
Writeanenumerationthatconformstothisprotocol.
NoticetheuseofthemutatingkeywordinthedeclarationofSimpleStructuretomarkamethodthatmodifiesthestructure.ThedeclarationofSimpleClassdoesn’tneedanyofitsmethodsmarkedasmutatingbecausemethodsonaclasscanalwaysmodifytheclass.
Useextensiontoaddfunctionalitytoanexistingtype,suchasnewmethodsandcomputedproperties.
-
Youcanuseanextensiontoaddprotocolconformancetoatypethatisdeclaredelsewhere,oreventoatypethatyouimportedfromalibraryorframework.
1 extensionInt:ExampleProtocol{
2 varsimpleDescription:String{
3 return"Thenumber\(self)"
4 }
5 mutatingfuncadjust(){
6 self+=42
7 }
8 }
9 print(7.simpleDescription)
EXPERIMEN T
WriteanextensionfortheDoubletypethataddsanabsoluteValueproperty.
Youcanuseaprotocolnamejustlikeanyothernamedtype—forexample,tocreateacollectionofobjectsthathavedifferenttypesbutthatallconformtoasingleprotocol.Whenyouworkwithvalueswhosetypeisaprotocoltype,methodsoutsidetheprotocoldefinitionarenotavailable.
1 letprotocolValue:ExampleProtocol=a
2 print(protocolValue.simpleDescription)
3 //print(protocolValue.anotherProperty)//Uncommenttoseetheerror
EventhoughthevariableprotocolValuehasaruntimetypeofSimpleClass,thecompilertreatsitasthegiventypeofExampleProtocol.Thismeansthatyoucan’taccidentallyaccessmethodsorpropertiesthattheclassimplementsinadditiontoitsprotocolconformance.
ErrorHandling
YourepresenterrorsusinganytypethatadoptstheErrorprotocol.
-
1 enumPrinterError:Error{
2 caseoutOfPaper
3 casenoToner
4 caseonFire
5 }
Usethrowtothrowanerrorandthrowstomarkafunctionthatcanthrowanerror.Ifyouthrowanerrorinafunction,thefunctionreturnsimmediatelyandthecodethatcalledthefunctionhandlestheerror.
1 funcsend(job:Int,toPrinterprinterName:String)throws->String{
2 ifprinterName=="NeverHasToner"{
3 throwPrinterError.noToner
4 }
5 return"Jobsent"
6 }
Thereareseveralwaystohandleerrors.Onewayistousedo-catch.Insidethedoblock,youmarkcodethatcanthrowanerrorbywritingtryinfrontofit.Insidethecatchblock,theerrorisautomaticallygiventhenameerrorunlessyougiveitadifferentname.
1 do{
2 letprinterResponse=trysend(job:1040,toPrinter:"BiSheng")
3 print(printerResponse)
4 }catch{
5 print(error)
6 }
EXPERIMEN T
Changetheprinternameto"NeverHasToner",sothatthesend(job:toPrinter:)functionthrowsanerror.
-
Youcanprovidemultiplecatchblocksthathandlespecificerrors.Youwriteapatternaftercatchjustasyoudoaftercaseinaswitch.
1 do{
2 letprinterResponse=trysend(job:1440,toPrinter:"Gutenberg")
3 print(printerResponse)
4 }catchPrinterError.onFire{
5 print("I'lljustputthisoverhere,withtherestofthefire.")
6 }catchletprinterErrorasPrinterError{
7 print("Printererror:\(printerError).")
8 }catch{
9 print(error)
}
EXPERIMEN T
Addcodetothrowanerrorinsidethedoblock.Whatkindoferrordoyouneedtothrowsothattheerrorishandledbythefirstcatchblock?Whataboutthesecondandthirdblocks?
Anotherwaytohandleerrorsistousetry?toconverttheresulttoanoptional.Ifthefunctionthrowsanerror,thespecificerrorisdiscardedandtheresultisnil.Otherwise,theresultisanoptionalcontainingthevaluethatthefunctionreturned.
1 letprinterSuccess=try?send(job:1884,toPrinter:"Mergenthaler")
2 letprinterFailure=try?send(job:1885,toPrinter:"NeverHasToner")
Usedefertowriteablockofcodethatisexecutedafterallothercodeinthefunction,justbeforethefunctionreturns.Thecodeisexecutedregardlessofwhetherthefunctionthrowsanerror.Youcanusedefertowritesetupandcleanupcodenexttoeachother,eventhoughtheyneedtobeexecutedatdifferenttimes.
-
1 varfridgeIsOpen=false
2 letfridgeContent=["milk","eggs","leftovers"]
3
4 funcfridgeContains(_food:String)->Bool{
5 fridgeIsOpen=true
6 defer{
7 fridgeIsOpen=false
8 }
9
letresult=fridgeContent.contains(food)
returnresult
}
fridgeContains("banana")
print(fridgeIsOpen)
Generics
Writeanameinsideanglebracketstomakeagenericfunctionortype.
1 funcmakeArray(repeatingitem:Item,numberOfTimes:Int)->[Item]{
2 varresult=[Item]()
3 for_in0..
-
Youcanmakegenericformsoffunctionsandmethods,aswellasclasses,enumerations,andstructures.
1 //ReimplementtheSwiftstandardlibrary'soptionaltype
2 enumOptionalValue{
3 casenone
4 casesome(Wrapped)
5 }
6 varpossibleInteger:OptionalValue=.none
7 possibleInteger=.some(100)
Usewhererightbeforethebodytospecifyalistofrequirements—forexample,torequirethetypetoimplementaprotocol,torequiretwotypestobethesame,ortorequireaclasstohaveaparticularsuperclass.
1 funcanyCommonElements(_lhs:T,_rhs:U)->Bool
2 whereT.Iterator.Element:Equatable,T.Iterator.Element==U.Iterator.Element{
3 forlhsIteminlhs{
4 forrhsIteminrhs{
5 iflhsItem==rhsItem{
6 returntrue
7 }
8 }
9 }
returnfalse
}
anyCommonElements([1,2,3],[3])
-
EXPERIMEN T
ModifytheanyCommonElements(_:_:)functiontomakeafunctionthatreturnsanarrayoftheelementsthatanytwosequenceshaveincommon.
Writingisthesameaswriting...whereT:Equatable>.
-
LanguageGuide
-
TheBasics
SwiftisanewprogramminglanguageforiOS,macOS,watchOS,andtvOSappdevelopment.Nonetheless,manypartsofSwiftwillbefamiliarfromyourexperienceofdevelopinginCandObjective-C.
SwiftprovidesitsownversionsofallfundamentalCandObjective-Ctypes,includingIntforintegers,DoubleandFloatforfloating-pointvalues,BoolforBooleanvalues,andStringfortextualdata.Swiftalsoprovidespowerfulversionsofthethreeprimarycollectiontypes,Array,Set,andDictionary,asdescribedinCollectionTypes.
LikeC,Swiftusesvariablestostoreandrefertovaluesbyanidentifyingname.Swiftalsomakesextensiveuseofvariableswhosevaluescannotbechanged.Theseareknownasconstants,andaremuchmorepowerfulthanconstantsinC.ConstantsareusedthroughoutSwifttomakecodesaferandclearerinintentwhenyouworkwithvaluesthatdonotneedtochange.
Inadditiontofamiliartypes,SwiftintroducesadvancedtypesnotfoundinObjective-C,suchastuples.Tuplesenableyoutocreateandpassaroundgroupingsofvalues.Youcanuseatupletoreturnmultiplevaluesfromafunctionasasinglecompoundvalue.
Swiftalsointroducesoptionaltypes,whichhandletheabsenceofavalue.Optionalssayeither“thereisavalue,anditequalsx”or“thereisn’tavalueatall”.UsingoptionalsissimilartousingnilwithpointersinObjective-C,buttheyworkforanytype,notjustclasses.NotonlyareoptionalssaferandmoreexpressivethannilpointersinObjective-C,theyareattheheartofmanyofSwift’smostpowerfulfeatures.
Swiftisatype-safelanguage,whichmeansthelanguagehelpsyoutobeclearaboutthetypesofvaluesyourcodecanworkwith.IfpartofyourcodeexpectsaString,typesafetypreventsyoufrompassingitanIntbymistake.Likewise,typesafetypreventsyoufromaccidentallypassinganoptionalStringtoapieceofcodethatexpectsanonoptionalString.Typesafetyhelpsyoucatchandfixerrorsasearlyaspossibleinthedevelopmentprocess.
ConstantsandVariables
Constantsandvariablesassociateaname(suchasmaximumNumberOfLoginAttemptsorwelcomeMessage)withavalueofaparticulartype(suchasthenumber10orthestring"Hello").Thevalueofaconstantcannotbechangedonceitisset,whereasavariablecanbesettoadifferentvalueinthefuture.
DeclaringConstantsandVariables
-
Constantsandvariablesmustbedeclaredbeforetheyareused.Youdeclareconstantswiththeletkeywordandvariableswiththevarkeyword.Here’sanexampleofhowconstantsandvariablescanbeusedtotrackthenumberofloginattemptsauserhasmade:
1 letmaximumNumberOfLoginAttempts=10
2 varcurrentLoginAttempt=0
Thiscodecanbereadas:
“DeclareanewconstantcalledmaximumNumberOfLoginAttempts,andgiveitavalueof10.Then,declareanewvariablecalledcurrentLoginAttempt,andgiveitaninitialvalueof0.”
Inthisexample,themaximumnumberofallowedloginattemptsisdeclaredasaconstant,becausethemaximumvalueneverchanges.Thecurrentloginattemptcounterisdeclaredasavariable,becausethisvaluemustbeincrementedaftereachfailedloginattempt.
Youcandeclaremultipleconstantsormultiplevariablesonasingleline,separatedbycommas:
varx=0.0,y=0.0,z=0.0
NOTE
Ifastoredvalueinyourcodeisnotgoingtochange,alwaysdeclareitasaconstantwiththeletkeyword.Usevariablesonlyforstoringvaluesthatneedtobeabletochange.
TypeAnnotations
Youcanprovideatypeannotationwhenyoudeclareaconstantorvariable,tobeclearaboutthekindofvaluestheconstantorvariablecanstore.Writeatypeannotationbyplacingacolonaftertheconstantorvariablename,followedbyaspace,followedbythenameofthetypetouse.
ThisexampleprovidesatypeannotationforavariablecalledwelcomeMessage,toindicatethatthevariablecanstoreStringvalues:
varwelcomeMessage:String
Thecoloninthedeclarationmeans“…oftype…,”sothecodeabovecanbereadas:
“DeclareavariablecalledwelcomeMessagethatisoftypeString.”
Thephrase“oftypeString”means“canstoreanyStringvalue.”Thinkofitasmeaning“thetypeofthing”(or“thekindofthing”)thatcanbestored.
-
ThewelcomeMessagevariablecannowbesettoanystringvaluewithouterror:
welcomeMessage="Hello"
Youcandefinemultiplerelatedvariablesofthesametypeonasingleline,separatedbycommas,withasingletypeannotationafterthefinalvariablename:
varred,green,blue:Double
NOTE
Itisrarethatyouneedtowritetypeannotationsinpractice.Ifyouprovideaninitialvalueforaconstantorvariableatthepointthatitisdefined,Swiftcanalmostalwaysinferthetypetobeusedforthatconstantorvariable,asdescribedinTypeSafetyandTypeInference.InthewelcomeMessageexampleabove,noinitialvalueisprovided,andsothetypeofthewelcomeMessagevariableisspecifiedwithatypeannotationratherthanbeinginferredfromaninitialvalue.
NamingConstantsandVariables
Constantandvariablenamescancontainalmostanycharacter,includingUnicodecharacters:
1 letπ=3.14159
2 let你好="你好世界"
3 let ="dogcow"
Constantandvariablenamescannotcontainwhitespacecharacters,mathematicalsymbols,arrows,private-use(orinvalid)Unicodecodepoints,orline-andbox-drawingcharacters.Norcantheybeginwithanumber,althoughnumbersmaybeincludedelsewherewithinthename.
Onceyou’vedeclaredaconstantorvariableofacertaintype,youcan’tredeclareitagainwiththesamename,orchangeittostorevaluesofadifferenttype.Norcanyouchangeaconstantintoavariableoravariableintoaconstant.
NOTE
IfyouneedtogiveaconstantorvariablethesamenameasareservedSwiftkeyword,surroundthekeywordwithbackticks(`)whenusingitasaname.However,avoidusingkeywordsasnamesunlessyouhaveabsolutelynochoice.
Youcanchangethevalueofanexistingvariabletoanothervalueofacompatibletype.Inthis
-
example,thevalueoffriendlyWelcomeischangedfrom"Hello!"to"Bonjour!":
1 varfriendlyWelcome="Hello!"
2 friendlyWelcome="Bonjour!"
3 //friendlyWelcomeisnow"Bonjour!"
Unlikeavariable,thevalueofaconstantcannotbechangedonceitisset.Attemptingtodosoisreportedasanerrorwhenyourcodeiscompiled:
1 letlanguageName="Swift"
2 languageName="Swift++"
3 //Thisisacompile-timeerror:languageNamecannotbechanged.
PrintingConstantsandVariables
Youcanprintthecurrentvalueofaconstantorvariablewiththeprint(_:separator:terminator:)function:
1 print(friendlyWelcome)
2 //Prints"Bonjour!"
Theprint(_:separator:terminator:)functionisaglobalfunctionthatprintsoneormorevaluestoanappropriateoutput.InXcode,forexample,theprint(_:separator:terminator:)functionprintsitsoutputinXcode’s“console”pane.Theseparatorandterminatorparameterhavedefaultvalues,soyoucanomitthemwhenyoucallthisfunction.Bydefault,thefunctionterminatesthelineitprintsbyaddingalinebreak.Toprintavaluewithoutalinebreakafterit,passanemptystringastheterminator—forexample,print(someValue,terminator:"").Forinformationaboutparameterswithdefaultvalues,seeDefaultParameterValues.
Swiftusesstringinterpolationtoincludethenameofaconstantorvariableasaplaceholderinalongerstring,andtopromptSwifttoreplaceitwiththecurrentvalueofthatconstantorvariable.Wrapthenameinparenthesesandescapeitwithabackslashbeforetheopeningparenthesis:
1 print("ThecurrentvalueoffriendlyWelcomeis\(friendlyWelcome)")
2 //Prints"ThecurrentvalueoffriendlyWelcomeisBonjour!"
-
NOTE
AlloptionsyoucanusewithstringinterpolationaredescribedinStringInterpolation.
Comments
Usecommentstoincludenonexecutabletextinyourcode,asanoteorremindertoyourself.CommentsareignoredbytheSwiftcompilerwhenyourcodeiscompiled.
CommentsinSwiftareverysimilartocommentsinC.Single-linecommentsbeginwithtwoforward-slashes(//):
//Thisisacomment.
Multilinecommentsstartwithaforward-slashfollowedbyanasterisk(/*)andendwithanasteriskfollowedbyaforward-slash(*/):
1 /*Thisisalsoacomment
2 butiswrittenovermultiplelines.*/
UnlikemultilinecommentsinC,multilinecommentsinSwiftcanbenestedinsideothermultilinecomments.Youwritenestedcommentsbystartingamultilinecommentblockandthenstartingasecondmultilinecommentwithinthefirstblock.Thesecondblockisthenclosed,followedbythefirstblock:
1 /*Thisisthestartofthefirstmultilinecomment.
2 /*Thisisthesecond,nestedmultilinecomment.*/
3 Thisistheendofthefirstmultilinecomment.*/
Nestedmultilinecommentsenableyoutocommentoutlargeblocksofcodequicklyandeasily,evenifthecodealreadycontainsmultilinecomments.
Semicolons
Unlikemanyotherlanguages,Swiftdoesnotrequireyoutowriteasemicolon(;)aftereachstatementinyourcode,althoughyoucandosoifyouwish.However,semicolonsarerequiredifyouwanttowritemultipleseparatestatementsonasingleline:
-
1 letcat=" ";print(cat)
2 //Prints" "
Integers
Integersarewholenumberswithnofractionalcomponent,suchas42and-23.Integersareeithersigned(positive,zero,ornegative)orunsigned(positiveorzero).
Swiftprovidessignedandunsignedintegersin8,16,32,and64bitforms.TheseintegersfollowanamingconventionsimilartoC,inthatan8-bitunsignedintegerisoftypeUInt8,anda32-bitsignedintegerisoftypeInt32.LikealltypesinSwift,theseintegertypeshavecapitalizednames.
IntegerBounds
Youcanaccesstheminimumandmaximumvaluesofeachintegertypewithitsminandmaxproperties:
1 letminValue=UInt8.min//minValueisequalto0,andisoftypeUInt8
2 letmaxValue=UInt8.max//maxValueisequalto255,andisoftypeUInt8
Thevaluesofthesepropertiesareoftheappropriate-sizednumbertype(suchasUInt8intheexampleabove)andcanthereforebeusedinexpressionsalongsideothervaluesofthesametype.
Int
Inmostcases,youdon’tneedtopickaspecificsizeofintegertouseinyourcode.Swiftprovidesanadditionalintegertype,Int,whichhasthesamesizeasthecurrentplatform’snativewordsize:
Unlessyouneedtoworkwithaspecificsizeofinteger,alwaysuseIntforintegervaluesinyourcode.Thisaidscodeconsistencyandinteroperability.Evenon32-bitplatforms,Intcanstoreanyvaluebetween-2,147,483,648and2,147,483,647,andislargeenoughformanyintegerranges.
Ona32-bitplatform,IntisthesamesizeasInt32.•Ona64-bitplatform,IntisthesamesizeasInt64.•
-
UInt
Swiftalsoprovidesanunsignedintegertype,UInt,whichhasthesamesizeasthecurrentplatform’snativewordsize:
NOTE
UseUIntonlywhenyouspecificallyneedanunsignedintegertypewiththesamesizeastheplatform’snativewordsize.Ifthisisnotthecase,Intispreferred,evenwhenthevaluestobestoredareknowntobenon-negative.AconsistentuseofIntforintegervaluesaidscodeinteroperability,avoidstheneedtoconvertbetweendifferentnumbertypes,andmatchesintegertypeinference,asdescribedinTypeSafetyandTypeInference.
Floating-PointNumbers
Floating-pointnumbersarenumberswithafractionalcomponent,suchas3.14159,0.1,and-273.15.
Floating-pointtypescanrepresentamuchwiderrangeofvaluesthanintegertypes,andcanstorenumbersthataremuchlargerorsmallerthancanbestoredinanInt.Swiftprovidestwosignedfloating-pointnumbertypes:
NOTE
Doublehasaprecisionofatleast15decimaldigits,whereastheprecisionofFloatcanbeaslittleas6decimaldigits.Theappropriatefloating-pointtypetousedependsonthenatureandrangeofvaluesyouneedtoworkwithinyourcode.Insituationswhereeithertypewouldbeappropriate,Doubleispreferred.
TypeSafetyandTypeInference
Swiftisatype-safelanguage.Atypesafelanguageencouragesyoutobeclearaboutthetypesofvaluesyourcodecanworkwith.IfpartofyourcodeexpectsaString,youcan’tpassitanIntbymistake.
Ona32-bitplatform,UIntisthesamesizeasUInt32.•Ona64-bitplatform,UIntisthesamesizeasUInt64.•
Doublerepresentsa64-bitfloating-pointnumber.•Floatrepresentsa32-bitfloating-pointnumber.•
-
BecauseSwiftistypesafe,itperformstypecheckswhencompilingyourcodeandflagsanymismatchedtypesaserrors.Thisenablesyoutocatchandfixerrorsasearlyaspossibleinthedevelopmentprocess.
Type-checkinghelpsyouavoiderrorswhenyou’reworkingwithdifferenttypesofvalues.However,thisdoesn’tmeanthatyouhavetospecifythetypeofeveryconstantandvariablethatyoudeclare.Ifyoudon’tspecifythetypeofvalueyouneed,Swiftusestypeinferencetoworkouttheappropriatetype.Typeinferenceenablesacompilertodeducethetypeofaparticularexpressionautomaticallywhenitcompilesyourcode,simplybyexaminingthevaluesyouprovide.
Becauseoftypeinference,SwiftrequiresfarfewertypedeclarationsthanlanguagessuchasCorObjective-C.Constantsandvariablesarestillexplicitlytyped,butmuchoftheworkofspecifyingtheirtypeisdoneforyou.
Typeinferenceisparticularlyusefulwhenyoudeclareaconstantorvariablewithaninitialvalue.Thisisoftendonebyassigningaliteralvalue(orliteral)totheconstantorvariableatthepointthatyoudeclareit.(Aliteralvalueisavaluethatappearsdirectlyinyoursourcecode,suchas42and3.14159intheexamplesbelow.)
Forexample,ifyouassignaliteralvalueof42toanewconstantwithoutsayingwhattypeitis,SwiftinfersthatyouwanttheconstanttobeanInt,becauseyouhaveinitializeditwithanumberthatlookslikeaninteger:
1 letmeaningOfLife=42
2 //meaningOfLifeisinferredtobeoftypeInt
Likewise,ifyoudon’tspecifyatypeforafloating-pointliteral,SwiftinfersthatyouwanttocreateaDouble:
1 letpi=3.14159
2 //piisinferredtobeoftypeDouble
SwiftalwayschoosesDouble(ratherthanFloat)wheninferringthetypeoffloating-pointnumbers.
Ifyoucombineintegerandfloating-pointliteralsinanexpression,atypeofDoublewillbeinferredfromthecontext:
1 letanotherPi=3+0.14159
2 //anotherPiisalsoinferredtobeoftypeDouble
Theliteralvalueof3hasnoexplicittypeinandofitself,andsoanappropriateoutputtypeofDoubleisinferredfromthepresenceofafloating-pointliteralaspartoftheaddition.
-
NumericLiterals
Integerliteralscanbewrittenas:
Alloftheseintegerliteralshaveadecimalvalueof17:
1 letdecimalInteger=17
2 letbinaryInteger=0b10001//17inbinarynotation
3 letoctalInteger=0o21//17inoctalnotation
4 lethexadecimalInteger=0x11//17inhexadecimalnotation
Floating-pointliteralscanbedecimal(withnoprefix),orhexadecimal(witha0xprefix).Theymustalwayshaveanumber(orhexadecimalnumber)onbothsidesofthedecimalpoint.Decimalfloatscanalsohaveanoptionalexponent,indicatedbyanuppercaseorlowercasee;hexadecimalfloatsmusthaveanexponent,indicatedbyanuppercaseorlowercasep.
Fordecimalnumberswithanexponentofexp,thebasenumberismultipliedby10exp:
Forhexadecimalnumberswithanexponentofexp,thebasenumberismultipliedby2exp:
Allofthesefloating-pointliteralshaveadecimalvalueof12.1875:
Adecimalnumber,withnoprefix•Abinarynumber,witha0bprefix•Anoctalnumber,witha0oprefix•Ahexadecimalnumber,witha0xprefix•
1.25e2means1.25x102,or125.0.•
1.25e-2means1.25x10-2,or0.0125.•
0xFp2means15x22,or60.0.•
0xFp-2means15x2-2,or3.75.•
-
1 letdecimalDouble=12.1875
2 letexponentDouble=1.21875e1
3 lethexadecimalDouble=0xC.3p0
Numericliteralscancontainextraformattingtomakethemeasiertoread.Bothintegersandfloatscanbepaddedwithextrazerosandcancontainunderscorestohelpwithreadability.Neithertypeofformattingaffectstheunderlyingvalueoftheliteral:
1 letpaddedDouble=000123.456
2 letoneMillion=1_000_000
3 letjustOverOneMillion=1_000_000.000_000_1
NumericTypeConversion
UsetheInttypeforallgeneral-purposeintegerconstantsandvariablesinyourcode,eveniftheyareknowntobenon-negative.Usingthedefaultintegertypeineverydaysituationsmeansthatintegerconstantsandvariablesareimmediatelyinteroperableinyourcodeandwillmatchtheinferredtypeforintegerliteralvalues.
Useotherintegertypesonlywhentheyarespecificallyneededforthetaskathand,becauseofexplicitly-sizeddatafromanexternalsource,orforperformance,memoryusage,orothernecessaryoptimization.Usingexplicitly-sizedtypesinthesesituationshelpstocatchanyaccidentalvalueoverflowsandimplicitlydocumentsthenatureofthedatabeingused.
IntegerConversion
Therangeofnumbersthatcanbestoredinanintegerconstantorvariableisdifferentforeachnumerictype.AnInt8constantorvariablecanstorenumbersbetween-128and127,whereasaUInt8constantorvariablecanstorenumbersbetween0and255.Anumberthatwillnotfitintoaconstantorvariableofasizedintegertypeisreportedasanerrorwhenyourcodeiscompiled:
-
1 letcannotBeNegative:UInt8=-1
2 //UInt8cannotstorenegativenumbers,andsothiswillreportanerror
3 lettooBig:Int8=Int8.max+1
4 //Int8cannotstoreanumberlargerthanitsmaximumvalue,
5 //andsothiswillalsoreportanerror
Becauseeachnumerictypecanstoreadifferentrangeofvalues,youmustoptintonumerictypeconversiononacase-by-casebasis.Thisopt-inapproachpreventshiddenconversionerrorsandhelpsmaketypeconversionintentionsexplicitinyourcode.
Toconvertonespecificnumbertypetoanother,youinitializeanewnumberofthedesiredtypewiththeexistingvalue.Intheexamplebelow,theconstanttwoThousandisoftypeUInt16,whereastheconstantoneisoftypeUInt8.Theycannotbeaddedtogetherdirectly,becausetheyarenotofthesametype.Instead,thisexamplecallsUInt16(one)tocreateanewUInt16initializedwiththevalueofone,andusesthisvalueinplaceoftheoriginal:
1 lettwoThousand:UInt16=2_000
2 letone:UInt8=1
3 lettwoThousandAndOne=twoThousand+UInt16(one)
BecausebothsidesoftheadditionarenowoftypeUInt16,theadditionisallowed.Theoutputconstant(twoThousandAndOne)isinferredtobeoftypeUInt16,becauseitisthesumoftwoUInt16values.
SomeType(ofInitialValue)isthedefaultwaytocalltheinitializerofaSwifttypeandpassinaninitialvalue.Behindthescenes,UInt16hasaninitializerthatacceptsaUInt8value,andsothisinitializerisusedtomakeanewUInt16fromanexistingUInt8.Youcan’tpassinanytypehere,however—ithastobeatypeforwhichUInt16providesaninitializer.Extendingexistingtypestoprovideinitializersthatacceptnewtypes(includingyourowntypedefinitions)iscoveredinExtensions.
IntegerandFloating-PointConversion
Conversionsbetweenintegerandfloating-pointnumerictypesmustbemadeexplicit:
-
1 letthree=3
2 letpointOneFourOneFiveNine=0.14159
3 letpi=Double(three)+pointOneFourOneFiveNine
4 //piequals3.14159,andisinferredtobeoftypeDouble
Here,thevalueoftheconstantthreeisusedtocreateanewvalueoftypeDouble,sothatbothsidesoftheadditionareofthesametype.Withoutthisconversioninplace,theadditionwouldnotbeallowed.
Floating-pointtointegerconversionmustalsobemadeexplicit.AnintegertypecanbeinitializedwithaDoubleorFloatvalue:
1 letintegerPi=Int(pi)
2 //integerPiequals3,andisinferredtobeoftypeInt
Floating-pointvaluesarealwaystruncatedwhenusedtoinitializeanewintegervalueinthisway.Thismeansthat4.75becomes4,and-3.9becomes-3.
NOTE
Therulesforcombiningnumericconstantsandvariablesaredifferentfromtherulesfornumericliterals.Theliteralvalue3canbeaddeddirectlytotheliteralvalue0.14159,becausenumberliteralsdonothaveanexplicittypeinandofthemselves.Theirtypeisinferredonlyatthepointthattheyareevaluatedbythecompiler.
TypeAliases
Typealiasesdefineanalternativenameforanexistingtype.Youdefinetypealiaseswiththetypealiaskeyword.
Typealiasesareusefulwhenyouwanttorefertoanexistingtypebyanamethatiscontextuallymoreappropriate,suchaswhenworkingwithdataofaspecificsizefromanexternalsource:
typealiasAudioSample=UInt16
Onceyoudefineatypealias,youcanusethealiasanywhereyoumightusetheoriginalname:
1 varmaxAmplitudeFound=AudioSample.min
2 //maxAmplitudeFoundisnow0
-
Here,AudioSampleisdefinedasanaliasforUInt16.Becauseitisanalias,thecalltoAudioSample.minactuallycallsUInt16.min,whichprovidesaninitialvalueof0forthemaxAmplitudeFoundvariable.
Booleans
SwifthasabasicBooleantype,calledBool.Booleanvaluesarereferredtoaslogical,becausetheycanonlyeverbetrueorfalse.SwiftprovidestwoBooleanconstantvalues,trueandfalse:
1 letorangesAreOrange=true
2 letturnipsAreDelicious=false
ThetypesoforangesAreOrangeandturnipsAreDelicioushavebeeninferredasBoolfromthefactthattheywereinitializedwithBooleanliteralvalues.AswithIntandDoubleabove,youdon’tneedtodeclareconstantsorvariablesasBoolifyousetthemtotrueorfalseassoonasyoucreatethem.TypeinferencehelpsmakeSwiftcodemoreconciseandreadablewhenitinitializesconstantsorvariableswithothervalueswhosetypeisalreadyknown.
Booleanvaluesareparticularlyusefulwhenyouworkwithconditionalstatementssuchastheifstatement:
1 ifturnipsAreDelicious{
2 print("Mmm,tastyturnips!")
3 }else{
4 print("Eww,turnipsarehorrible.")
5 }
6 //Prints"Eww,turnipsarehorrible."
ConditionalstatementssuchastheifstatementarecoveredinmoredetailinControlFlow.
Swift’stypesafetypreventsnon-BooleanvaluesfrombeingsubstitutedforBool.Thefollowingexamplereportsacompile-timeerror:
1 leti=1
2 ifi{
3 //thisexamplewillnotcompile,andwillreportanerror
4 }
-
However,thealternativeexamplebelowisvalid:
1 leti=1
2 ifi==1{
3 //thisexamplewillcompilesuccessfully
4 }
Theresultofthei==1comparisonisoftypeBool,andsothissecondexamplepassesthetype-check.Comparisonslikei==1arediscussedinBasicOperators.
AswithotherexamplesoftypesafetyinSwift,thisapproachavoidsaccidentalerrorsandensuresthattheintentionofaparticularsectionofcodeisalwaysclear.
Tuples
Tuplesgroupmultiplevaluesintoasinglecompoundvalue.Thevalueswithinatuplecanbeofanytypeanddonothavetobeofthesametypeaseachother.
Inthisexample,(404,"NotFound")isatuplethatdescribesanHTTPstatuscode.AnHTTPstatuscodeisaspecialvaluereturnedbyawebserverwheneveryourequestawebpage.Astatuscodeof404NotFoundisreturnedifyourequestawebpagethatdoesn’texist.
1 lethttp404Error=(404,"NotFound")
2 //http404Errorisoftype(Int,String),andequals(404,"NotFound")
The(404,"NotFound")tuplegroupstogetheranIntandaStringtogivetheHTTPstatuscodetwoseparatevalues:anumberandahuman-readabledescription.Itcanbedescribedas“atupleoftype(Int,String)”.
Youcancreatetuplesfromanypermutationoftypes,andtheycancontainasmanydifferenttypesasyoulike.There’snothingstoppingyoufromhavingatupleoftype(Int,Int,Int),or(String,Bool),orindeedanyotherpermutationyourequire.
Youcandecomposeatuple’scontentsintoseparateconstantsorvariables,whichyouthenaccessasusual:
-
1 let(statusCode,statusMessage)=http404Error
2 print("Thestatuscodeis\(statusCode)")
3 //Prints"Thestatuscodeis404"
4 print("Thestatusmessageis\(statusMessage)")
5 //Prints"ThestatusmessageisNotFound"
Ifyouonlyneedsomeofthetuple’svalues,ignorepartsofthetuplewithanunderscore(_)whenyoudecomposethetuple:
1 let(justTheStatusCode,_)=http404Error
2 print("Thestatuscodeis\(justTheStatusCode)")
3 //Prints"Thestatuscodeis404"
Alternatively,accesstheindividualelementvaluesinatupleusingindexnumbersstartingatzero:
1 print("Thestatuscodeis\(http404Error.0)")
2 //Prints"Thestatuscodeis404"
3 print("Thestatusmessageis\(http404Error.1)")
4 //Prints"ThestatusmessageisNotFound"
Youcannametheindividualelementsinatuplewhenthetupleisdefined:
lethttp200Status=(statusCode:200,description:"OK")
Ifyounametheelementsinatuple,youcanusetheelementnamestoaccessthevaluesofthoseelements:
1 print("Thestatuscodeis\(http200Status.statusCode)")
2 //Prints"Thestatuscodeis200"
3 print("Thestatusmessageis\(http200Status.description)")
4 //Prints"ThestatusmessageisOK"
Tuplesareparticularlyusefulasthereturnvaluesoffunctions.Afunctionthattriestoretrieveawebpagemightreturnthe(Int,String)tupletypetodescribethesuccessorfailureofthepageretrieval.
-
Byreturningatuplewithtwodistinctvalues,eachofadifferenttype,thefunctionprovidesmoreusefulinformationaboutitsoutcomethanifitcouldonlyreturnasinglevalueofasingletype.Formoreinformation,seeFunctionswithMultipleReturnValues.
NOTE
Tuplesareusefulfortemporarygroupsofrelatedvalues.Theyarenotsuitedtothecreationofcomplexdatastructures.Ifyourdatastructureislikelytopersistbeyondatemporaryscope,modelitasaclassorstructure,ratherthanasatuple.Formoreinformation,seeClassesandStructures.
Optionals
Youuseoptionalsinsituationswhereavaluemaybeabsent.Anoptionalrepresentstwopossibilities:Eitherthereisavalue,andyoucanunwraptheoptionaltoaccessthatvalue,orthereisn’tavalueatall.
NOTE
Theconceptofoptionalsdoesn’texistinCorObjective-C.ThenearestthinginObjective-Cistheabilitytoreturnnilfromamethodthatwouldotherwisereturnanobject,withnilmeaning“theabsenceofavalidobject.”However,thisonlyworksforobjects—itdoesn’tworkforstructures,basicCtypes,orenumerationvalues.Forthesetypes,Objective-Cmethodstypicallyreturnaspecialvalue(suchasNSNotFound)toindicatetheabsenceofavalue.Thisapproachassumesthatthemethod’scallerknowsthereisaspecialvaluetotestagainstandrememberstocheckforit.Swift’soptionalsletyouindicatetheabsenceofavalueforanytypeatall,withouttheneedforspecialconstants.
Here’sanexampleofhowoptionalscanbeusedtocopewiththeabsenceofavalue.Swift’sInttypehasaninitializerwhichtriestoconvertaStringvalueintoanIntvalue.However,noteverystringcanbeconvertedintoaninteger.Thestring"123"canbeconvertedintothenumericvalue123,butthestring"hello,world"doesnothaveanobviousnumericvaluetoconvertto.
TheexamplebelowusestheinitializertotrytoconvertaStringintoanInt:
1 letpossibleNumber="123"
2 letconvertedNumber=Int(possibleNumber)
3 //convertedNumberisinferredtobeoftype"Int?",or"optionalInt"
Becausetheinitializermightfail,itreturnsanoptionalInt,ratherthananInt.AnoptionalIntiswrittenasInt?,notInt.Thequestionmarkindicatesthatthevalueitcontainsisoptional,meaningthatitmightcontainsomeIntvalue,oritmightcontainnovalueatall.(Itcan’tcontainanythingelse,suchasaBoolvalueoraStringvalue.It’seitheranInt,orit’snothingatall.)
-
nil
Yousetanoptionalvariabletoavaluelessstatebyassigningitthespecialvaluenil:
1 varserverResponseCode:Int?=404
2 //serverResponseCodecontainsanactualIntvalueof404
3 serverResponseCode=nil
4 //serverResponseCodenowcontainsnovalue
NOTE
nilcannotbeusedwithnonoptionalconstantsandvariables.Ifaconstantorvariableinyourcodeneedstoworkwiththeabsenceofavalueundercertainconditions,alwaysdeclareitasanoptionalvalueoftheappropriatetype.
Ifyoudefineanoptionalvariablewithoutprovidingadefaultvalue,thevariableisautomaticallysettonilforyou:
1 varsurveyAnswer:String?
2 //surveyAnswerisautomaticallysettonil
NOTE
Swift’snilisnotthesameasnilinObjective-C.InObjective-C,nilisapointertoanonexistentobject.InSwift,nilisnotapointer—itistheabsenceofavalueofacertaintype.Optionalsofanytypecanbesettonil,notjustobjecttypes.
IfStatementsandForcedUnwrapping
Youcanuseanifstatementtofindoutwhetheranoptionalcontainsavaluebycomparingtheoptionalagainstnil.Youperformthiscomparisonwiththe“equalto”operator(==)orthe“notequalto”operator(!=).
Ifanoptionalhasavalue,itisconsideredtobe“notequalto”nil:
-
1 ifconvertedNumber!=nil{
2 print("convertedNumbercontainssomeintegervalue.")
3 }
4 //Prints"convertedNumbercontainssomeintegervalue."
Onceyou’resurethattheoptionaldoescontainavalue,youcanaccessitsunderlyingvaluebyaddinganexclamationmark(!)totheendoftheoptional’sname.Theexclamationmarkeffectivelysays,“Iknowthatthisoptionaldefinitelyhasavalue;pleaseuseit.”Thisisknownasforcedunwrappingoftheoptional’svalue:
1 ifconvertedNumber!=nil{
2 print("convertedNumberhasanintegervalueof\(convertedNumber!).")
3 }
4 //Prints"convertedNumberhasanintegervalueof123."
Formoreontheifstatement,seeControlFlow.
NOTE
Tryingtouse!toaccessanonexistentoptionalvaluetriggersaruntimeerror.Alwaysmakesurethatanoptionalcontainsanon-nilvaluebeforeusing!toforce-unwrapitsvalue.
OptionalBinding
Youuseoptionalbindingtofindoutwhetheranoptionalcontainsavalue,andifso,tomakethatvalueavailableasatemporaryconstantorvariable.Optionalbindingcanbeusedwithifandwhilestatementstocheckforavalueinsideanoptional,andtoextractthatvalueintoaconstantorvariable,aspartofasingleaction.ifandwhilestatementsaredescribedinmoredetailinControlFlow.
Writeanoptionalbindingforanifstatementasfollows:
iflet constantName = someOptional {
statements
}
-
YoucanrewritethepossibleNumberexamplefromtheOptionalssectiontouseoptionalbindingratherthanforcedunwrapping:
1 ifletactualNumber=Int(possibleNumber){
2 print("\"\(possibleNumber)\"hasanintegervalueof\(actualNumber)")
3 }else{
4 print("\"\(possibleNumber)\"couldnotbeconvertedtoaninteger")
5 }
6 //Prints""123"hasanintegervalueof123"
Thiscodecanbereadas:
“IftheoptionalIntreturnedbyInt(possibleNumber)containsavalue,setanewconstantcalledactualNumbertothevaluecontainedintheoptional.”
Iftheconversionissuccessful,theactualNumberconstantbecomesavailableforusewithinthefirstbranchoftheifstatement.Ithasalreadybeeninitializedwiththevaluecontainedwithintheoptional,andsothereisnoneedtousethe!suffixtoaccessitsvalue.Inthisexample,actualNumberissimplyusedtoprinttheresultoftheconversion.
Youcanusebothconstantsandvariableswithoptionalbinding.IfyouwantedtomanipulatethevalueofactualNumberwithinthefirstbranchoftheifstatement,youcouldwriteifvaractualNumberinstead,andthevaluecontainedwithintheoptionalwouldbemadeavailableasavariableratherthanaconstant.
YoucanincludeasmanyoptionalbindingsandBooleanconditionsinasingleifstatementasyouneedto,separatedbycommas.IfanyofthevaluesintheoptionalbindingsareniloranyBooleanconditionevaluatestofalse,thewholeifstatement’sconditionisconsideredtobefalse.Thefollowingifstatementsareequivalent:
-
1 ifletfirstNumber=Int("4"),letsecondNumber=Int("42"),firstNumber<
secondNumber&&secondNumber<100{
2 print("\(firstNumber)<\(secondNumber)<100")
3 }
4 //Prints"4<42<100"
5
6 ifletfirstNumber=Int("4"){
7 ifletsecondNumber=Int("42"){
8 iffirstNumber<secondNumber&&secondNumber<100{
9 print("\(firstNumber)<\(secondNumber)<100")
}
}
}
//Prints"4<42<100"
NOTE
Constantsandvariablescreatedwithoptionalbindinginanifstatementareavailableonlywithinthebodyoftheifstatement.Incontrast,theconstantsandvariablescreatedwithaguardstatementareavailableinthelinesofcodethatfollowtheguardstatement,asdescribedinEarlyExit.
ImplicitlyUnwrappedOptionals
Asdescribedabove,optionalsindicatethataconstantorvariableisallowedtohave“novalue”.Optionalscanbecheckedwithanifstatementtoseeifavalueexists,andcanbeconditionallyunwrappedwithoptionalbindingtoaccesstheoptional’svalueifitdoesexist.
Sometimesitisclearfromaprogram’sstructurethatanoptionalwillalwayshaveavalue,afterthatvalueisfirstset.Inthesecases,itisusefultoremovetheneedtocheckandunwraptheoptional’svalueeverytimeitisaccessed,becauseitcanbesafelyassumedtohaveavalueallofthetime.
Thesekindsofoptionalsaredefinedasimplicitlyunwrappedoptionals.Youwriteanimplicitlyunwrappedoptionalbyplacinganexclamationmark(String!)ratherthanaquestionmark(String?)
-
afterthetypethatyouwanttomakeoptional.
Implicitlyunwrappedoptionalsareusefulwhenanoptional’svalueisconfirmedtoexistimmediatelyaftertheoptionalisfirstdefinedandcandefinitelybeassumedtoexistateverypointthereafter.TheprimaryuseofimplicitlyunwrappedoptionalsinSwiftisduringclassinitialization,asdescribedinUnownedReferencesandImplicitlyUnwrappedOptionalProperties.
Animplicitlyunwrappedoptionalisanormaloptionalbehindthescenes,butcanalsobeusedlikeanonoptionalvalue,withouttheneedtounwraptheoptionalvalueeachtimeitisaccessed.ThefollowingexampleshowsthedifferenceinbehaviorbetweenanoptionalstringandanimplicitlyunwrappedoptionalstringwhenaccessingtheirwrappedvalueasanexplicitString:
1 letpossibleString:String?="Anoptionalstring."
2 letforcedString:String=possibleString!//requiresanexclamationmark
3
4 letassumedString:String!="Animplicitlyunwrappedoptionalstring."
5 letimplicitString:String=assumedString//noneedforanexclamationmark
Youcanthinkofanimplicitlyunwrappedoptionalasgivingpermissionfortheoptionaltobeunwrappedautomaticallywheneveritisused.Ratherthanplacinganexclamationmarkaftertheoptional’snameeachtimeyouuseit,youplaceanexclamationmarkaftertheoptional’stypewhenyoudeclareit.
NOTE
Ifanimplicitlyunwrappedoptionalisnilandyoutrytoaccessitswrappedvalue,you’lltriggeraruntimeerror.Theresultisexactlythesameasifyouplaceanexclamationmarkafteranormaloptionalthatdoesnotcontainavalue.
Youcanstilltreatanimplicitlyunwrappedoptionallikeanormaloptional,tocheckifitcontainsavalue:
1 ifassumedString!=nil{
2 print(assumedString)
3 }
4 //Prints"Animplicitlyunwrappedoptionalstring."
Youcanalsouseanimplicitlyunwrappedoptionalwithoptionalbinding,tocheckandunwrapitsvalueinasinglestatement:
-
1 ifletdefiniteString=assumedString{
2 print(definiteString)
3 }
4 //Prints"Animplicitlyunwrappedoptionalstring."
NOTE
Donotuseanimplicitlyunwrappedoptionalwhenthereisapossibilityofavariablebecomingnilatalaterpoint.Alwaysuseanormaloptionaltypeifyouneedtocheckforanilvalueduringthelifetimeofavariable.
ErrorHandling
Youuseerrorhandlingtorespondtoerrorconditionsyourprogrammayencounterduringexecution.
Incontrasttooptionals,whichcanusethepresenceorabsenceofavaluetocommunicatesuccessorfailureofafunction,errorhandlingallowsyoutodeterminetheunderlyingcauseoffailure,and,ifnecessary,propagatetheerrortoanotherpartofyourprogram.
Whenafunctionencountersanerrorcondition,itthrowsanerror.Thatfunction’scallercanthencatchtheerrorandrespondappropriately.
1 funccanThrowAnError()throws{
2 //thisfunctionmayormaynotthrowanerror
3 }
Afunctionindicatesthatitcanthrowanerrorbyincludingthethrowskeywordinitsdeclaration.Whenyoucallafunctionthatcanthrowanerror,youprependthetrykeywordtotheexpression.
Swiftautomaticallypropagateserrorsoutoftheircurrentscopeuntiltheyarehandledbyacatchclause.
-
1 do{
2 trycanThrowAnError()
3 //noerrorwasthrown
4 }catch{
5 //anerrorwasthrown
6 }
Adostatementcreatesanewcontainingscope,whichallowserrorstobepropagatedtooneormorecatchclauses.
Here’sanexampleofhowerrorhandlingcanbeusedtorespondtodifferenterrorconditions:
1 funcmakeASandwich()throws{
2 //...
3 }
4
5 do{
6 trymakeASandwich()
7 eatASandwich()
8 }catchSandwichError.outOfCleanDishes{
9 washDishes()
}catchSandwichError.missingIngredients(letingredients){
buyGroceries(ingredients)
}
Inthisexample,themakeASandwich()functionwillthrowanerrorifnocleandishesareavailableorifanyingredientsaremissing.BecausemakeASandwich()canthrowanerror,thefunctioncalliswrappedinatryexpression.Bywrappingthefunctioncallinadostatement,anyerrorsthatarethrownwillbepropagatedtotheprovidedcatchclauses.
Ifnoerroristhrown,theeatASandwich()functioniscalled.IfanerroristhrownanditmatchestheSandwichError.outOfCleanDishescase,thenthewashDishes()functionwillbecalled.IfanerroristhrownanditmatchestheSandwichError.missingIngredientscase,thenthebuyGroceries(_:)function
-
iscalledwiththeassociated[String]valuecapturedbythecatchpattern.
Throwing,catching,andpropagatingerrorsiscoveredingreaterdetailinErrorHandling.
Assertions
Insomecases,itissimplynotpossibleforyourcodetocontinueexecutionifaparticularconditionisnotsatisfied.Inthesesituations,youcantriggeranassertioninyourcodetoendcodeexecutionandtoprovideanopportunitytodebugthecauseoftheabsentorinvalidvalue.
DebuggingwithAssertions
AnassertionisaruntimecheckthataBooleanconditiondefinitelyevaluatestotrue.Literallyput,anassertion“asserts”thataconditionistrue.Youuseanassertiontomakesurethatanessentialconditionissatisfiedbeforeexecutinganyfurthercode.Iftheconditionevaluatestotrue,codeexecutioncontinuesasusual;iftheconditionevaluatestofalse,codeexecutionends,andyourappisterminated.
Ifyourcodetriggersanassertionwhilerunninginadebugenvironment,suchaswhenyoubuildandrunanappinXcode,youcanseeexactlywheretheinvalidstateoccurredandquerythestateofyourappatthetimethattheassertionwastriggered.Anassertionalsoletsyouprovideasuitabledebugmessageastothenatureoftheassert.
YouwriteanassertionbycallingtheSwiftstandardlibraryglobalassert(_:_:file:line:)function.Youpassthisfunctionanexpressionthatevaluatestotrueorfalseandamessagethatshouldbedisplayediftheresultoftheconditionisfalse:
1 letage=-3
2 assert(age>=0,"Aperson'sagecannotbelessthanzero")
3 //thiscausestheassertiontotrigger,becauseageisnot>=0
Inthisexample,codeexecutionwillcontinueonlyifage>=0evaluatestotrue,thatis,ifthevalueofageisnon-negative.Ifthevalueofageisnegative,asinthecodeabove,thenage>=0evaluatestofalse,andtheassertionistriggered,terminatingtheapplication.
Theassertionmessagecanbeomittedifdesired,asinthefollowingexample:
assert(age>=0)
-
NOTE
Assertionsaredisabledwhenyourcodeiscompiledwithoptimizations,suchaswhenbuildingwithanapptarget’sdefaultReleaseconfigurationinXcode.
WhentoUseAssertions
Useanassertionwheneveraconditionhasthepotentialtobefalse,butmustdefinitelybetrueinorderforyourcodetocontinueexecution.Suitablescenariosforanassertioncheckinclude:
SeealsoSubscriptsandFunctions.
NOTE
Assertionscauseyourapptoterminateandarenotasubstitutefordesigningyourcodeinsuchawaythatinvalidconditionsareunlikelytoarise.Nonetheless,insituationswhereinvalidconditionsarepossible,anassertionisaneffectivewaytoensurethatsuchconditionsarehighlightedandnoticedduringdevelopment,beforeyourappispublished.
Anintegersubscriptindexispassedtoacustomsubscriptimplementation,butthesubscriptindexvaluecouldbetoolowortoohigh.
•
Avalueispassedtoafunction,butaninvalidvaluemeansthatthefunctioncannotfulfillitstask.
•
Anoptionalvalueiscurrentlynil,butanon-nilvalueisessentialforsubsequentcodetoexecutesuccessfully.
•
-
BasicOperators
Anoperatorisaspecialsymbolorphrasethatyouusetocheck,change,orcombinevalues.Forexample,theadditionoperator(+)addstwonumbers,asinleti=1+2,andthelogicalANDoperator(&&)combinestwoBooleanvalues,asinifenteredDoorCode&&passedRetinaScan.
SwiftsupportsmoststandardCoperatorsandimprovesseveralcapabilitiestoeliminatecommoncodingerrors.Theassignmentoperator(=)doesnotreturnavalue,topreventitfrombeingmistakenlyusedwhentheequaltooperator(==)isintended.Arithmeticoperators(+,-,*,/,%andsoforth)detectanddisallowvalueoverflow,toavoidunexpectedresultswhenworkingwithnumbersthatbecomelargerorsmallerthantheallowedvaluerangeofthetypethatstoresthem.YoucanoptintovalueoverflowbehaviorbyusingSwift’soverflowoperators,asdescribedinOverflowOperators.
Swiftalsoprovidestworangeoperators(a..
-
1 letb=10
2 vara=5
3 a=b
4 //aisnowequalto10
Iftherightsideoftheassignmentisatuplewithmultiplevalues,itselementscanbedecomposedintomultipleconstantsorvariablesatonce:
1 let(x,y)=(1,2)
2 //xisequalto1,andyisequalto2
UnliketheassignmentoperatorinCandObjective-C,theassignmentoperatorinSwiftdoesnotitselfreturnavalue.Thefollowingstatementisnotvalid:
1 ifx=y{
2 //Thisisnotvalid,becausex=ydoesnotreturnavalue.
3 }
Thisfeaturepreventstheassignmentoperator(=)frombeingusedbyaccidentwhentheequaltooperator(==)isactuallyintended.Bymakingifx=yinvalid,Swifthelpsyoutoavoidthesekindsoferrorsinyourcode.
ArithmeticOperators
Swiftsupportsthefourstandardarithmeticoperatorsforallnumbertypes:
Addition(+)•Subtraction(-)•Multiplication(*)•Division(/)•
-
1 1+2//equals3
2 5-3//equals2
3 2*3//equals6
4 10.0/2.5//equals4.0
UnlikethearithmeticoperatorsinCandObjective-C,theSwiftarithmeticoperatorsdonotallowvaluestooverflowbydefault.YoucanoptintovalueoverflowbehaviorbyusingSwift’soverflowoperators(suchasa&+b).SeeOverflowOperators.
TheadditionoperatorisalsosupportedforStringconcatenation:
"hello,"+"world"//equals"hello,world"
RemainderOperator
Theremainderoperator(a%b)worksouthowmanymultiplesofbwillfitinsideaandreturnsthevaluethatisleftover(knownastheremainder).
NOTE
Theremainderoperator(%)isalsoknownasamodulooperatorinotherlanguages.However,itsbehaviorinSwiftfornegativenumbersmeansthatitis,strictlyspeaking,aremainderratherthanamodulooperation.
Here’showtheremainderoperatorworks.Tocalculate9%4,youfirstworkouthowmany4swillfitinside9:
Youcanfittwo4sinside9,andtheremainderis1(showninorange).
InSwift,thiswouldbewrittenas:
9%4//equals1
Todeterminetheanswerfora%b,the%operatorcalculatesthefollowingequationandreturnsremainderasitsoutput:
-
a=(bxsomemultiplier)+remainder
wheresomemultiplieristhelargestnumberofmultiplesofbthatwillfitinsidea.
Inserting9and4intothisequationyields:
9=(4x2)+1
Thesamemethodisappliedwhencalculatingtheremainderforanegativevalueofa:
-9%4//equals-1
Inserting-9and4intotheequationyields:
-9=(4x-2)+-1
givingaremaindervalueof-1.
Thesignofbisignoredfornegativevaluesofb.Thismeansthata%banda%-balwaysgivethesameanswer.
UnaryMinusOperator
Thesignofanumericvaluecanbetoggledusingaprefixed-,knownastheunaryminusoperator:
1 letthree=3
2 letminusThree=-three//minusThreeequals-3
3 letplusThree=-minusThree//plusThreeequals3,or"minusminusthree"
Theunaryminusoperator(-)isprependeddirectlybeforethevalueitoperateson,withoutanywhitespace.
UnaryPlusOperator
Theunaryplusoperator(+)simplyreturnsthevalueitoperateson,withoutanychange:
1 letminusSix=-6
2 letalsoMinusSix=+minusSix//alsoMinusSixequals-6
Althoughtheunaryplusoperatordoesn’tactuallydoanything,youcanuseittoprovidesymmetryinyourcodeforpositivenumberswhenalsousingtheunaryminusoperatorfornegativenumbers.
-
CompoundAssignmentOperators
LikeC,Swiftprovidescompoundassignmentoperatorsthatcombineassignment(=)withanotheroperation.Oneexampleistheadditionassignmentoperator(+=):
1 vara=1
2 a+=2
3 //aisnowequalto3
Theexpressiona+=2isshorthandfora=a+2.Effectively,theadditionandtheassignmentarecombinedintooneoperatorthatperformsbothtasksatthesametime.
NOTE
Thecompoundassignmentoperatorsdonotreturnavalue.Forexample,youcannotwriteletb=a+=2.
ForacompletelistofthecompoundassignmentoperatorsprovidedbytheSwiftstandardlibrary,seeSwiftStandardLibraryOperatorsReference.
ComparisonOperators
SwiftsupportsallstandardCcomparisonoperators:
NOTE
Swiftalsoprovidestwoidentityoperators(===and!==),whichyouusetotestwhethertwoobjectreferencesbothrefertothesameobjectinstance.Formoreinformation,seeClassesandStructures.
Equalto(a==b)•Notequalto(a!=b)•Greaterthan(a>b)•Lessthan(a<b)•Greaterthanorequalto(a>=b)•Lessthanorequalto(a
-
EachofthecomparisonoperatorsreturnsaBoolvaluetoindicatewhetherornotthestatementistrue:
1 1==1//truebecause1isequalto1
2 2!=1//truebecause2isnotequalto1
3 2>1//truebecause2isgreaterthan1
4 1<2//truebecause1islessthan2
5 1>=1//truebecause1isgreaterthanorequalto1
6 2
-
1 (1,"zebra")<(2,"apple")//truebecause1islessthan2;"zebra"and"apple"
arenotcompared
2 (3,"apple")<(3,"bird")//truebecause3isequalto3,and"apple"isless
than"bird"
3 (4,"dog")==(4,"dog")//truebecause4isequalto4,and"dog"isequalto
"dog"
Intheexampleabove,youcanseetheleft-to-rightcomparisonbehavioronthefirstline.Because1islessthan2,(1,"zebra")isconsideredlessthan(2,"apple"),regardlessofanyothervaluesinthetuples.Itdoesn’tmatterthat"zebra"isn’tlessthan"apple",becausethecomparisonisalreadydeterminedbythetuples’firstelements.However,whenthetuples’firstelementsarethesame,theirsecondelementsarecompared—thisiswhathappensonthesecondandthirdline.
NOTE
TheSwiftstandardlibraryincludestuplecomparisonoperatorsfortupleswithfewerthansevenelements.Tocomparetupleswithsevenormoreelements,youmustimplementthecomparisonoperatorsyourself.
TernaryConditionalOperator
Theternaryconditionaloperatorisaspecialoperatorwiththreeparts,whichtakestheformquestion?answer1:answer2.Itisashortcutforevaluatingoneoftwoexpressionsbasedonwhetherquestionistrueorfalse.Ifquestionistrue,itevaluatesanswer1andreturnsitsvalue;otherwise,itevaluatesanswer2andreturnsitsvalue.
Theternaryconditionaloperatorisshorthandforthecodebelow:
1 ifquestion{
2 answer1
3 }else{
4 answer2
5 }
Here’sanexample,whichcalculatestheheightforatablerow.Therowheightshouldbe50pointstallerthanthecontentheightiftherowhasaheader,and20pointstalleriftherowdoesn’thavea
-
header:
1 letcontentHeight=40
2 lethasHeader=true
3 letrowHeight=contentHeight+(hasHeader?50:20)
4 //rowHeightisequalto90
Theprecedingexampleisshorthandforthecodebelow:
1 letcontentHeight=40
2 lethasHeader=true
3 letrowHeight:Int
4 ifhasHeader{
5 rowHeight=contentHeight+50
6 }else{
7 rowHeight=contentHeight+20
8 }
9 //rowHeightisequalto90
Thefirstexample’suseoftheternaryconditionaloperatormeansthatrowHeightcanbesettothecorrectvalueonasinglelineofcode,whichismoreconcisethanthecodeusedinthesecondexample.
Theternaryconditionaloperatorprovidesanefficientshorthandfordecidingwhichoftwoexpressionstoconsider.Usetheternaryconditionaloperatorwithcare,however.Itsconcisenesscanleadtohard-to-readcodeifoverused.Avoidcombiningmultipleinstancesoftheternaryconditionaloperatorintoonecompoundstatement.
Nil-CoalescingOperator
Thenil-coalescingoperator(a??b)unwrapsanoptionalaifitcontainsavalue,orreturnsadefaultvaluebifaisnil.Theexpressionaisalwaysofanoptionaltype.Theexpressionbmustmatchthetypethatisstoredinsidea.
Thenil-coalescingoperatorisshorthandforthecodebelow:
-
a!=nil?a!:b
Thecodeaboveusestheternaryconditionaloperatorandforcedunwrapping(a!)toaccessthevaluewrappedinsideawhenaisnotnil,andtoreturnbotherwise.Thenil-coalescingoperatorprovidesamoreelegantwaytoencapsulatethisconditionalcheckingandunwrappinginaconciseandreadableform.
NOTE
Ifthevalueofaisnon-nil,thevalueofbisnotevaluated.Thisisknownasshort-circuitevaluation.
Theexamplebelowusesthenil-coalescingoperatortochoosebetweenadefaultcolornameandanoptionaluser-definedcolorname:
1 letdefaultColorName="red"
2 varuserDefinedColorName:String?//defaultstonil
3
4 varcolorNameToUse=userDefinedColorName??defaultColorName
5 //userDefinedColorNameisnil,socolorNameToUseissettothedefaultof"red"
TheuserDefinedColorNamevariableisdefinedasanoptionalString,withadefaultvalueofnil.BecauseuserDefinedColorNameisofanoptionaltype,youcanusethenil-coalescingoperatortoconsideritsvalue.Intheexampleabove,theoperatorisusedtodetermineaninitialvalueforaStringvariablecalledcolorNameToUse.BecauseuserDefinedColorNameisnil,theexpressionuserDefinedColorName??defaultColorNamereturnsthevalueofdefaultColorName,or"red".
Ifyouassignanon-nilvaluetouserDefinedColorNameandperformthenil-coalescingoperatorcheckagain,thevaluewrappedinsideuserDefinedColorNameisusedinsteadofthedefault:
1 userDefinedColorName="green"
2 colorNameToUse=userDefinedColorName??defaultColorName
3 //userDefinedColorNameisnotnil,socolorNameToUseissetto"green"
RangeOperators
Swiftincludestworangeoperators,whichareshortcutsforexpressingarangeofvalues.
-
ClosedRangeOperator
Theclosedrangeoperator(a...b)definesarangethatrunsfromatob,andincludesthevaluesaandb.Thevalueofamustnotbegreaterthanb.
Theclosedrangeoperatorisusefulwheniteratingoverarangeinwhichyouwantallofthevaluestobeused,suchaswithafor-inloop:
1 forindexin1...5{
2 print("\(index)times5is\(index*5)")
3 }
4 //1times5is5
5 //2times5is10
6 //3times5is15
7 //4times5is20
8 //5times5is25
Formoreonfor-inloops,seeControlFlow.
Half-OpenRangeOperator
Thehalf-openrangeoperator(a..
-
1 letnames=["Anna","Alex","Brian","Jack"]
2 letcount=names.count
3 foriin0..
-
1 letallowedEntry=false
2 if!allowedEntry{
3 print("ACCESSDENIED")
4 }
5 //Prints"ACCESSDENIED"
Thephraseif!allowedEntrycanbereadas“ifnotallowedentry.”Thesubsequentlineisonlyexecutedif“notallowedentry”istrue;thatis,ifallowedEntryisfalse.
Asinthisexample,carefulchoiceofBooleanconstantandvariablenamescanhelptokeepcodereadableandconcise,whileavoidingdoublenegativesorconfusinglogicstatements.
LogicalANDOperator
ThelogicalANDoperator(a&&b)createslogicalexpressionswherebothvaluesmustbetruefortheoverallexpressiontoalsobetrue.
Ifeithervalueisfalse,theoverallexpressionwillalsobefalse.Infact,ifthefirstvalueisfalse,thesecondvaluewon’tevenbeevaluated,becauseitcan’tpossiblymaketheoverallexpressionequatetotrue.Thisisknownasshort-circuitevaluation.
ThisexampleconsiderstwoBoolvaluesandonlyallowsaccessifbothvaluesaretrue:
1 letenteredDoorCode=true
2 letpassedRetinaScan=false
3 ifenteredDoorCode&&passedRetinaScan{
4 print("Welcome!")
5 }else{
6 print("ACCESSDENIED")
7 }
8 //Prints"ACCESSDENIED"
LogicalOROperator
-
ThelogicalORoperator(a||b)isaninfixoperatormadefromtwoadjacentpipecharacters.Youuseittocreatelogicalexpressionsinwhichonlyoneofthetwovalueshastobetruefortheoverallexpressiontobetrue.
LiketheLogicalANDoperatorabove,theLogicalORoperatorusesshort-circuitevaluationtoconsideritsexpressions.IftheleftsideofaLogicalORexpressionistrue,therightsideisnotevaluated,becauseitcannotchangetheoutcomeoftheoverallexpression.
Intheexamplebelow,thefirstBoolvalue(hasDoorKey)isfalse,butthesecondvalue(knowsOverridePassword)istrue.Becauseonevalueistrue,theoverallexpressionalsoevaluatestotrue,andaccessisallowed:
1 lethasDoorKey=false
2 letknowsOverridePassword=true
3 ifhasDoorKey||knowsOverridePassword{
4 print("Welcome!")
5 }else{
6 print("ACCESSDENIED")
7 }
8 //Prints"Welcome!"
CombiningLogicalOperators
Youcancombinemultiplelogicaloperatorstocreatelongercompoundexpressions:
1 ifenteredDoorCode&&passedRetinaScan||hasDoorKey||knowsOverridePassword{
2 print("Welcome!")
3 }else{
4 print("ACCESSDENIED")
5 }
6 //Prints"Welcome!"
Thisexampleusesmultiple&&and||operatorstocreatealongercompoundexpression.How