Apple doc dice: Type casting è un modo per controllare il tipo di un’istanza o per trattare quell’istanza come una superclasse o sottoclasse diversa da qualche altra parte nella propria gerarchia di classi.

La fusione di tipo in Swift è implementata con gli operatori is e as. is viene utilizzato per controllare il tipo di un valore mentre as viene utilizzato per lanciare un valore su un tipo diverso.

Considera le seguenti classi LivingBeing e due sottoclassi di LivingBeing denominate Human e Animal .

Ora crea un array costante chiamato livingBeingArray con un oggetto di classe Animal e un oggetto di classe human. Cosa ne pensi del tipo di questo array creato tramite l’inferenza di tipo? Sarà di tipo .

Il correttore di tipi di Swift è in grado di dedurre che Human e Animal hanno una superclasse comune di LivingBeing, e quindi deduce un tipo di per l’array livingBeingArray.

Gli elementi memorizzati in livingBeingArray sono ancora Human e Animal istanze dietro le quinte. Tuttavia, se si itera il contenuto di questo array, gli elementi ricevuti vengono digitati come LivingBeing e non come Human o Animal. Per lavorare con loro come tipo nativo, è necessario controllare il loro tipo o ridurli a un tipo diverso.

Utilizzare l’operatore di controllo del tipo (is) per verificare se un’istanza è di un determinato tipo di sottoclasse. L’operatore type check restituisce true se l’istanza è di quel tipo di sottoclasse e false se non lo è.

Considera il seguente codice:

let livingBeingObj = livingBeingArray // returns a LivingBeing object.

Ripetiamo gli oggetti dell’array su un ciclo for.

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 dice: una costante o variabile di un certo tipo di classe può effettivamente fare riferimento a un’istanza di una sottoclasse dietro le quinte. Dove credi che questo sia il caso, puoi provare a eseguire il downcast al tipo di sottoclasse con un operatore di tipo cast (as? o as!).

Semplifichiamo questo. Considera l’array livingBeingArray. Sappiamo che il primo elemento è di tipo Animal. Poiché l’array contiene un oggetto Animal e un oggetto Human, l’inferenza del tipo deciderà il tipo di array come LivingBeing. Se proviamo a ottenere qualsiasi contenuto da questo array, ti restituirà un oggetto di tipo LivingBeing.In tal caso possiamo provare a downcast dopo averlo recuperato dall’array.

Differenza tra as? e come!

Downcasting può essere fatto in due modi:

  • Downcasting condizionale (come?).
  • Downcasting forzato (as!).

Il modulo condizionale, as?, restituisce un valore facoltativo del tipo a cui si sta tentando di eseguire il downcast. La forma forzata, as!, tenta il downcast e forza-srotola il risultato come una singola azione composta.

Usa la forma condizionale dell’operatore di tipo cast (as?) quando non sei sicuro che il downcast avrà successo. Questa forma dell’operatore restituirà sempre un valore facoltativo e il valore sarà nil se il downcast non è stato possibile. Ciò consente di verificare la presenza di un downcast di successo.

Usa la forma forzata dell’operatore di tipo cast (as!) solo quando sei sicuro che il downcast avrà sempre successo. Questa forma dell’operatore attiverà un errore di runtime se si tenta di eseguire il downcast su un tipo di classe errato.

Qui nello scenario precedente, poiché sappiamo che il primo oggetto nell’array è di tipo Animal, possiamo usare il downcasting forzato.

let animalObj = livingBeingArray as! Animal //forced downcasting to Animallet humanObj = livingBeingArray as! Human //forced downcasting to Human

Ma il downcasting forzato può fallire se proviamo a downcastare il primo oggetto su un Humane il secondo oggetto su un Animal. In questo caso il risultato sarà nil che un tipo normale non può gestire e il programma si bloccherà.

let animalObj = livingBeingArray as! Human //error and crasheslet humanObj = livingBeingArray as! Animal //error and crashes

In questo scenario, dove non siamo sicuri se il casting ha successo, dovremmo usare il downcasting condizionale 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)

Ma il downcasting condizionale del tipo corretto ha esito positivo e restituisce il tipo opzionale corretto a cui stiamo cercando di eseguire il downcast.

let animalObj = livingBeingArray as? Animal // success, returns Animal?let humanObj = livingBeingArray as? Human // success, returns Human?

Upcasting

Upcasting dall’oggetto classe base alla sua superclasse è anche possibile. Convertiamo il animalObject creato dal downcasting forzato nella classe LivingBeing.

let animalObj = livingBeingArray as! Animal
let animalObjectAsLivingBeingObj = animalObj as LivingBeing

animalObjectAsLivingBeingObj è di tipo LivingBeing.

Tipo Casting per Any e AnyObject

Swift fornisce due tipi speciali per lavorare con tipi non specifici:

  • Any può rappresentare un’istanza di qualsiasi tipo, inclusi i tipi di funzione.
  • AnyObject può rappresentare un’istanza di qualsiasi tipo di classe.

Source: Internet

La parola chiave ‘Any’ viene utilizzata per rappresentare un’istanza che appartiene a qualsiasi tipo, inclusi i tipi di funzione. Si consideri un array di tipo Any che può accettare diversi tipi di valori. Possiamo usare un’istruzione switch per controllare il tipo e fare 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
*/

Il downcasting forzato e condizionale non funzionerà in un switch-case

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.