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 und as implementiert. is wird verwendet, um den Typ eines Werts zu überprüfen, während as 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 und Animal eine gemeinsame Oberklasse von LivingBeing haben, und leitet daher einen Typ von fü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? oder as!) 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.

Quelle: Internet

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.