¿Cuál es la diferencia entre is, as, as?, as! en swift? Bueno, veamos.
El documento de Apple dice: Type casting es una forma de verificar el tipo de una instancia, o de tratar esa instancia como una superclase o subclase diferente de otro lugar de su propia jerarquía de clases.
El casting de tipo en Swift se implementa con los operadores
is
yas
.is
se usa para verificar el tipo de un valor, mientras queas
se usa para convertir un valor a un tipo diferente.
Considere las siguientes clases LivingBeing
y dos subclases de LivingBeing
llamadas Human
y Animal
.
Ahora cree una matriz constante llamada livingBeingArray
con un objeto de clase Animal
y un objeto de clase human
. ¿Cuál crees que es el tipo de esta matriz creado a través de la inferencia de tipos? Será de tipo .
El comprobador de tipos de Swift es capaz de deducir que
Human
yAnimal
tienen una superclase común deLivingBeing
, por lo que infiere un tipo depara el array
livingBeingArray
.
Los elementos almacenados en livingBeingArray
siguen siendo Human
y Animal
instancias entre bastidores. Sin embargo, si itera sobre el contenido de esta matriz, los elementos que recibe se escriben como LivingBeing
, y no como Human
o Animal
. Para trabajar con ellos como su tipo nativo, debe verificar su tipo o bajarlos a un tipo diferente.
Utilice el operador de comprobación de tipo (is
) para comprobar si una instancia es de un tipo de subclase determinado. El operador de comprobación de tipo devuelve true
si la instancia es de ese tipo de subclase y false
si no lo es.
Considere el siguiente código:
let livingBeingObj = livingBeingArray // returns a LivingBeing object.
Vamos a iterar los objetos de matriz sobre un bucle 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
El documento de Apple dice: Una constante o variable de cierto tipo de clase puede referirse a una instancia de una subclase detrás de escena. Cuando crea que este es el caso, puede intentar bajar al tipo de subclase con un operador de conversión de tipo (
as?
oas!
).
Simplifiquemos esto. Considere la matriz livingBeingArray
. Sabemos que el primer elemento es de tipo Animal
. Dado que la matriz contiene un objeto Animal
y un objeto Human
, la inferencia de tipos decidirá el tipo de matriz como LivingBeing
. Si intentamos obtener cualquier contenido de esta matriz, nos devolverá un objeto de tipo LivingBeing.
En ese caso podemos intentar bajarlo después de buscarlo de la matriz.
Diferencia entre as? ¡y as!
El downcasting se puede hacer de dos maneras:
- Downcasting condicional (como?).
- Downcasting forzado (as!).
La forma condicional, as?
, devuelve un valor opcional del tipo al que está tratando de bajar. La forma forzada, as!
, intenta la caída y la fuerza desenvuelve el resultado como una sola acción compuesta.
Utilice la forma condicional del operador de conversión de tipo (as?
) cuando no esté seguro de si la bajada tendrá éxito. Esta forma del operador siempre devolverá un valor opcional, y el valor será nil
si la bajada no fue posible. Esto le permite verificar si tiene un descenso exitoso.
Utilice la forma forzada del operador de fundición de tipo (as!
) solo cuando esté seguro de que la bajada siempre tendrá éxito. Esta forma del operador activará un error de tiempo de ejecución si intenta bajar a un tipo de clase incorrecto.
Aquí en el escenario anterior, ya que sabemos que el primer objeto en el array es de tipo Animal, podemos usar downcasting forzado.
let animalObj = livingBeingArray as! Animal //forced downcasting to Animallet humanObj = livingBeingArray as! Human //forced downcasting to Human
Pero el downcasting forzado puede fallar si intentamos bajar el primer objeto a Human
y el segundo objeto a Animal
. En este caso, el resultado será nil
que un tipo normal no puede manejar y el programa se bloqueará.
let animalObj = livingBeingArray as! Human //error and crasheslet humanObj = livingBeingArray as! Animal //error and crashes
En este escenario, donde no estamos seguros de si el casting tiene éxito, debemos usar el downcasting condicional 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)
Pero la difusión condicional del tipo correcto tiene éxito y devuelve el tipo opcional correcto al que estamos tratando de transmitir.
let animalObj = livingBeingArray as? Animal // success, returns Animal?let humanObj = livingBeingArray as? Human // success, returns Human?
Upcasting
Upcasting del objeto de clase base a su superclase también es posible. Vamos a convertir el animalObject
creado por reducción forzada a la clase LivingBeing
.
let animalObj = livingBeingArray as! Animal
let animalObjectAsLivingBeingObj = animalObj as LivingBeing
animalObjectAsLivingBeingObj
es de tipo LivingBeing
.
Fundición de tipos para Any y AnyObject
Swift proporciona dos tipos especiales para trabajar con tipos no específicos:
-
Any
puede representar una instancia de cualquier tipo, incluidos los tipos de funciones. -
AnyObject
puede representar una instancia de cualquier tipo de clase.

La palabra clave ‘ Any ‘ se utiliza para representar una instancia que pertenece a cualquier tipo, incluidos los tipos de funciones. Considere una matriz de tipo Any
que puede aceptar diferentes tipos de valores. Podemos usar una instrucción switch para verificar el tipo y hacer 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
*/
La transmisión forzada y condicional no funcionará en un
switch-case