Wat is het verschil tussen is, as, as? as! in swift? Laten we eens kijken.
Apple doc zegt: Type casting is een manier om het type van een instantie te controleren, of om die instantie te behandelen als een andere superklasse of subklasse dan ergens anders in zijn eigen klassenhiërarchie.
Type gieten in Swift wordt uitgevoerd met de operators
is
enas
.is
wordt gebruikt om het type van een waarde te controleren, terwijlas
wordt gebruikt om een waarde naar een ander type te gieten.
beschouw de volgende klassen LivingBeing
en twee subklassen van LivingBeing
met de naam Human
en Animal
.
Maak nu een constante array genaamd livingBeingArray
met één Animal
klasse object en één human
klasse object. Wat denk je dat het type van deze array gemaakt via Type gevolgtrekking? Het zal van het type zijn .
Swift ‘ S type checker kan afleiden dat
Human
enAnimal
een gemeenschappelijke superklasse vanLivingBeing
hebben, en dus leidt het een type vanaf voor de
livingBeingArray
array.
de items opgeslagen in livingBeingArray
zijn nog steeds Human
en Animal
exemplaren achter de schermen. Als u echter de inhoud van deze array herhaalt, worden de items die u terug ontvangt getypt als LivingBeing
, en niet als Human
of Animal
. Om te werken met hen als hun native type, je nodig hebt om hun type te controleren, of neercast ze naar een ander type.
gebruik de operator voor typecontrole (is
) om te controleren of een instantie van een bepaald subklasse-type is. De type check operator geeft true
terug als de instantie van dat subklasse type is en false
als dit niet het geval is.
beschouw de volgende code:
let livingBeingObj = livingBeingArray // returns a LivingBeing object.
laten we de array-objecten herhalen over een for
lus.
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 zegt: een constante of variabele van een bepaald klasse type kan eigenlijk verwijzen naar een instantie van een subklasse achter de schermen. Als u denkt dat dit het geval is, kunt u proberen om te downcast naar het subklasse type met een type cast operator (
as?
ofas!
).
laten we dit vereenvoudigen. Beschouw de array livingBeingArray
. We weten dat het eerste item van het type Animal
is . Aangezien array één Animal
object en één Human
object bevat, zal de type gevolgtrekking het array type bepalen als LivingBeing
. Als we proberen om enige inhoud van deze array te krijgen, zal het je een object van het type LivingBeing.
teruggeven In dat geval kunnen we proberen om het te downcast na het ophalen van het uit de array.
verschil tussen as? en als!
Downcasting kan op twee manieren:
- voorwaardelijke downcasting (als?).
- gedwongen downcasting (als!).
de conditionele vorm, as?
, geeft een optionele waarde terug van het type waarnaar u probeert te downcast. De geforceerde vorm, as!
, probeert de downcast en force-unwraps het resultaat als een enkele samengestelde actie.
gebruik de conditionele vorm van het type Cast operator (as?
) als u niet zeker weet of de downcast zal slagen. Deze vorm van de operator zal altijd een optionele waarde retourneren, en de waarde zal nil
zijn als de downcast niet mogelijk was. Dit stelt u in staat om te controleren op een succesvolle downcast.
gebruik de geforceerde vorm van het type cast operator (as!
) alleen als u er zeker van bent dat de downcast altijd zal slagen. Deze vorm van de operator zal een runtime-fout veroorzaken als u probeert te downcast naar een onjuist klasse-type.
hier in het bovenstaande scenario, omdat we weten dat het eerste object in de array van het type dier is, kunnen we geforceerde downcasting gebruiken.
let animalObj = livingBeingArray as! Animal //forced downcasting to Animallet humanObj = livingBeingArray as! Human //forced downcasting to Human
maar gedwongen downcasting kan mislukken als we proberen het eerste object naar een Human
en het tweede object naar een Animal
te downcast. In dit geval zal het resultaat nil
zijn wat een normaal type niet aankan en zal het programma crashen.
let animalObj = livingBeingArray as! Human //error and crasheslet humanObj = livingBeingArray as! Animal //error and crashes
In dit scenario, waar we niet zeker zijn of de casting slaagt, moeten we de voorwaardelijke downcasting as?
gebruiken .
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)
maar voorwaardelijke downcasting van het juiste type slaagt en geeft het juiste optionele type terug waarnaar we proberen te downcast.
let animalObj = livingBeingArray as? Animal // success, returns Animal?let humanObj = livingBeingArray as? Human // success, returns Human?
Upcasting
Upcasting van het basisklasse object naar zijn superklasse is ook mogelijk. Laten we de animalObject
die gemaakt is door gedwongen downcasting terug te zetten naar de LivingBeing
klasse.
let animalObj = livingBeingArray as! Animal
let animalObjectAsLivingBeingObj = animalObj as LivingBeing
animalObjectAsLivingBeingObj
is van het type LivingBeing
.
Type Casting voor elk en elk object
Swift biedt twee speciale types voor het werken met niet-specifieke types:
-
Any
kan een instantie van elk type vertegenwoordigen, inclusief functietypen. -
AnyObject
kan een instantie van elk klasse-type vertegenwoordigen.

het trefwoord ‘ Any ‘ wordt gebruikt om een instantie aan te geven die tot elk type behoort, met inbegrip van functietypen. Overweeg een array van type Any
die verschillende soorten waarden kan accepteren. We kunnen een switch statement gebruiken om het type te controleren en downcasting te doen.
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
*/
gedwongen en voorwaardelijke downcasting zal niet werken in een
switch-case