vad är skillnaden mellan is, as, as?, som! i swift? Tja, låt oss kolla.
Apple doc säger: typgjutning är ett sätt att kontrollera typen av en instans eller att behandla den instansen som en annan superklass eller underklass från någon annanstans i sin egen klasshierarki.
typgjutning i Swift implementeras med operatörerna
is
ochas
.is
används för att kontrollera typen av ett värde medanas
används för att kasta ett värde till en annan typ.
Tänk på följande klasser LivingBeing
och två underklasser av LivingBeing
med namnet Human
och Animal
.
skapa nu en konstant array som heter livingBeingArray
med ett Animal
klassobjekt och ett human
klassobjekt. Vad tror du vilken typ av denna array som skapats via Typ inferens? Det kommer att vara av typen .
Swifts typkontroll kan dra slutsatsen att
Human
ochAnimal
har en gemensam superklass avLivingBeing
, och så härleder den en typ avför
livingBeingArray
arrayen.
objekten som lagras i livingBeingArray
är fortfarande Human
och Animal
instanser bakom kulisserna. Men om du itererar över innehållet i den här matrisen skrivs de objekt du får tillbaka som LivingBeing
och inte som Human
eller Animal
. För att kunna arbeta med dem som sin ursprungliga typ måste du kontrollera deras typ eller nedkasta dem till en annan typ.
använd operatorn för typkontroll (is
) för att kontrollera om en instans är av en viss underklasstyp. Operatorn för typkontroll returnerar true
om instansen är av den typen av underklass och false
om den inte är det.
Tänk på följande kod:
let livingBeingObj = livingBeingArray // returns a LivingBeing object.
Låt oss iterera arrayobjekten över en for
– slinga.
for item in livingBeingArray {if item is Animal {print("item is of type Animal")// will get executed for first item} else if item is Human {print("item is of type Human")// will get executed for second item}}
Downcasting
Apple doc säger: en konstant eller variabel av en viss klass typ kan faktiskt hänvisa till en instans av en underklass bakom kulisserna. Om du tror att detta är fallet kan du försöka nedkasta till underklasstypen med en typgjutningsoperatör (
as?
elleras!
).
låt oss förenkla detta. Tänk på matrisen livingBeingArray
. Vi vet att det första objektet är av typen Animal
. Eftersom array innehåller ett Animal
– objekt och ett Human
– objekt, bestämmer typavslutningen arraytypen som LivingBeing
. Om vi försöker få något innehåll från den här arrayen kommer det att returnera ett objekt av typen LivingBeing.
i så fall kan vi försöka nedkasta det efter att ha hämtat det från arrayen.
skillnad mellan as? och som!
Downcasting kan göras på två sätt:
- villkorlig downcasting (som?).
- tvingas downcasting (som!).
den villkorliga formen, as?
, returnerar ett valfritt värde av den typ du försöker nedkasta till. Den tvingade formen, as!
, försöker nedslagen och tvingar upp resultatet som en enda sammansatt åtgärd.
använd den villkorliga formen av typen cast operator (as?
) när du inte är säker på om den nedslagna kommer att lyckas. Denna form av operatören returnerar alltid ett valfritt värde, och värdet kommer att vara nil
om nedslaget inte var möjligt. Detta gör att du kan söka efter en lyckad nedslagen.
använd den tvingade formen av typen cast operator (as!
) endast när du är säker på att nedslaget alltid kommer att lyckas. Denna form av operatören kommer att utlösa ett runtime-fel om du försöker nedkasta till en felaktig klasstyp.
här i ovanstående scenario, eftersom vi vet att det första objektet i matrisen är av typen djur, kan vi använda Tvingad nedkastning.
let animalObj = livingBeingArray as! Animal //forced downcasting to Animallet humanObj = livingBeingArray as! Human //forced downcasting to Human
men Tvingad nedkastning kan misslyckas om vi försöker nedkasta det första objektet till ett Human
och det andra objektet till ett Animal
. I detta fall blir resultatet nil
som en normal typ inte kan hantera och programmet kommer att krascha.
let animalObj = livingBeingArray as! Human //error and crasheslet humanObj = livingBeingArray as! Animal //error and crashes
i det här scenariot, där vi inte är säkra på om gjutningen lyckas, bör vi använda den villkorliga nedkastningen as?
.
let animalObj = livingBeingArray as? Human //nil..animalObj is of Human? (optional Human which is the type which we tried to downcast to)let humanObj = livingBeingArray as? Animal //nil..humanObj is of Animal? (optional Animal which is the type which we tried to downcast to)
men villkorlig nedkastning av rätt typ lyckas och returnerar rätt valfri typ som vi försöker nedkasta till.
let animalObj = livingBeingArray as? Animal // success, returns Animal?let humanObj = livingBeingArray as? Human // success, returns Human?
Upcasting
Upcasting från basklassobjektet till dess superklass är också möjligt. Låt oss Konvertera animalObject
skapad av tvingad nedkastning tillbaka till klassen LivingBeing
.
let animalObj = livingBeingArray as! Animal
let animalObjectAsLivingBeingObj = animalObj as LivingBeing
animalObjectAsLivingBeingObj
är av typ LivingBeing
.
typgjutning för alla och AnyObject
Swift ger två speciella typer för att arbeta med icke-specifika typer:
-
Any
kan representera en instans av vilken typ som helst, inklusive funktionstyper. -
AnyObject
kan representera en instans av vilken klass som helst.

nyckelordet ’Any’ används för att representera en instans som tillhör vilken typ som helst inklusive funktionstyper. Tänk på en array av typen Any
som kan acceptera olika typer av värden. Vi kan använda ett switch-uttalande för att kontrollera typen och göra downcasting.
var groups = ()
groups.append(1.0)
groups.append(1)
groups.append("string")
for item in groups {
switch item {
case let anInt as Int:
print("\(item) is an int")
case let aDouble as Double:
print("\(item) is a double")
case let aString as String:
print("\(item) is a string")
default:
print("dunno")
}
}
/*
1.0 is a double
1 is an int
string is a string
C11lldb_expr_13Pop (has 1 child) is a Genre
*/
Tvingad och villkorad nedkastning fungerar inte i en
switch-case