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 och as. is används för att kontrollera typen av ett värde medan as 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 och Animal har en gemensam superklass av LivingBeing, och så härleder den en typ av fö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? eller as!).

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.

källa: Internet

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

Lämna ett svar

Din e-postadress kommer inte publiceras.