Was ist der Unterschied zwischen is, as, as?, wie! in Swift? Nun, lass uns nachsehen.
Apple doc sagt: Type Casting ist eine Möglichkeit, den Typ einer Instanz zu überprüfen oder diese Instanz als eine andere Oberklasse oder Unterklasse von einer anderen Stelle in ihrer eigenen Klassenhierarchie zu behandeln.
Die Typumwandlung in Swift wird mit den Operatoren
is
undas
implementiert.is
wird verwendet, um den Typ eines Werts zu überprüfen, währendas
verwendet wird, um einen Wert in einen anderen Typ umzuwandeln.
Betrachten Sie die folgenden Klassen LivingBeing
und zwei Unterklassen von LivingBeing
mit den Namen Human
und Animal
.
Erstellen Sie nun ein konstantes Array mit dem Namen livingBeingArray
mit einem Animal
Klassenobjekt und einem human
Klassenobjekt. Was denken Sie, ist der Typ dieses Arrays, das über Typinferenz erstellt wurde? Es wird vom Typ sein.
Swifts Typprüfer kann ableiten, dass
Human
undAnimal
eine gemeinsame Oberklasse vonLivingBeing
haben, und leitet daher einen Typ vonfür das Array
livingBeingArray
ab.
Die in livingBeingArray
gespeicherten Elemente sind immer noch Human
und Animal
Instanzen hinter den Kulissen. Wenn Sie jedoch den Inhalt dieses Arrays durchlaufen, werden die Elemente, die Sie zurückerhalten, als LivingBeing
und nicht als Human
oder Animal
eingegeben. Um mit ihnen als nativem Typ arbeiten zu können, müssen Sie ihren Typ überprüfen oder auf einen anderen Typ herunterstufen.
Verwenden Sie den Typprüfungsoperator (is
), um zu überprüfen, ob eine Instanz einem bestimmten Unterklassentyp angehört. Der Typprüfungsoperator gibt true
zurück, wenn die Instanz von diesem Unterklassentyp ist, und false
, wenn dies nicht der Fall ist.
Betrachten Sie den folgenden Code:
let livingBeingObj = livingBeingArray // returns a LivingBeing object.
Lassen Sie uns die Array-Objekte über eine for
-Schleife iterieren.
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 sagt: Eine Konstante oder Variable eines bestimmten Klassentyps kann sich tatsächlich auf eine Instanz einer Unterklasse hinter den Kulissen beziehen. Wenn Sie glauben, dass dies der Fall ist, können Sie versuchen, mit einem Typumwandlungsoperator (
as?
oderas!
) auf den Unterklassentyp herabzusetzen.
Vereinfachen wir das. Betrachten Sie das Array livingBeingArray
. Wir wissen, dass das erste Element vom Typ Animal
ist. Da das Array ein Animal
-Objekt und ein Human
-Objekt enthält, entscheidet die Typinferenz über den Array-Typ als LivingBeing
. Wenn wir versuchen, Inhalte aus diesem Array abzurufen, erhalten Sie ein Objekt vom Typ LivingBeing.
In diesem Fall können wir versuchen, es nach dem Abrufen aus dem Array herunterzuspielen.
Unterschied zwischen as? und wie!
Downcasting kann auf zwei Arten erfolgen:
- Bedingtes Downcasting (wie?).
- Erzwungenes Downcasting (wie!).
Das bedingte Formular as?
gibt einen optionalen Wert des Typs zurück, auf den Sie herabsetzen möchten. Die erzwungene Form as!
versucht das Niedergeschlagene und entpackt das Ergebnis als eine einzige zusammengesetzte Aktion.
Verwenden Sie die bedingte Form des Typumwandlungsoperators (as?
), wenn Sie nicht sicher sind, ob der Downcast erfolgreich sein wird. Diese Form des Operators gibt immer einen optionalen Wert zurück, und der Wert ist nil
, wenn der Downcast nicht möglich war. Auf diese Weise können Sie nach einem erfolgreichen Downcast suchen.
Verwenden Sie die erzwungene Form des Typumwandlungsoperators (as!
) nur, wenn Sie sicher sind, dass der Downcast immer erfolgreich ist. Diese Form des Operators löst einen Laufzeitfehler aus, wenn Sie versuchen, auf einen falschen Klassentyp herunterzustufen.
Hier im obigen Szenario können wir, da wir wissen, dass das erste Objekt im Array vom Typ Animal ist, erzwungenes Downcasting verwenden.
let animalObj = livingBeingArray as! Animal //forced downcasting to Animallet humanObj = livingBeingArray as! Human //forced downcasting to Human
Das erzwungene Downcasting kann jedoch fehlschlagen, wenn wir versuchen, das erste Objekt auf ein Human
und das zweite Objekt auf ein Animal
. In diesem Fall lautet das Ergebnis nil
, was ein normaler Typ nicht verarbeiten kann, und das Programm stürzt ab.
let animalObj = livingBeingArray as! Human //error and crasheslet humanObj = livingBeingArray as! Animal //error and crashes
In diesem Szenario, in dem wir nicht sicher sind, ob das Casting erfolgreich ist, sollten wir das bedingte Downcasting 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)
Das bedingte Downcasting des richtigen Typs ist jedoch erfolgreich und gibt den richtigen optionalen Typ zurück, auf den heruntergestuft werden soll.
let animalObj = livingBeingArray as? Animal // success, returns Animal?let humanObj = livingBeingArray as? Human // success, returns Human?
Upcasting
Upcasting vom Basisklassenobjekt zu seiner Oberklasse ist ebenfalls möglich. Konvertieren wir das animalObject
, das durch erzwungenes Downcasting erstellt wurde, zurück in die LivingBeing
-Klasse.
let animalObj = livingBeingArray as! Animal
let animalObjectAsLivingBeingObj = animalObj as LivingBeing
animalObjectAsLivingBeingObj
ist vom Typ LivingBeing
.
Type Casting für Any und AnyObject
Swift bietet zwei spezielle Typen für die Arbeit mit unspezifischen Typen:
-
Any
kann eine Instanz eines beliebigen Typs darstellen, einschließlich Funktionstypen. -
AnyObject
kann eine Instanz eines beliebigen Klassentyps darstellen.

Das Schlüsselwort ‚Any‘ wird verwendet, um eine Instanz darzustellen, die zu einem beliebigen Typ einschließlich Funktionstypen gehört. Betrachten Sie ein Array vom Typ Any
, das verschiedene Arten von Werten akzeptieren kann. Wir können eine switch-Anweisung verwenden, um den Typ zu überprüfen und Downcasting durchzuführen.
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
*/
Erzwungenes und bedingtes Downcasting funktioniert nicht in einem
switch-case