0Pricing
Swift Academy · Lección

Conversión forzada con as! y sus riesgos

Utilice as! solo cuando tenga la certeza de que la conversión funcionará.

Conversión forzada con as! y sus riesgos es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

Conversión forzada

El operador de conversión forzada as! realiza una conversión descendente y desenvuelve el resultado en un solo paso. Proporciona directamente el tipo no opcional, pero provoca un error si la conversión falla.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let dog = a as! Dog
print(dog.bark())

Sin envolver en un opcional

A diferencia de as?, el resultado de as! es el tipo normal, no un opcional. No hay nada que desenvolver.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let dog: Dog = a as! Dog
print(type(of: dog))

El riesgo de as!

Si la instancia no es realmente del tipo de destino, as! provoca un error en tiempo de ejecución y detiene el programa. No hay forma de recuperarse.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
// let cat = a as! Cat  // would crash at runtime
print("Only force-cast when certain")

Cuándo es segura la conversión forzada

Use as! solo cuando tenga la certeza absoluta del tipo, por ejemplo, justo después de comprobarlo con is.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if a is Dog {
    let dog = a as! Dog
    print(dog.bark())
}

Conversión forzada tras una garantía

Si la lógica del código garantiza el tipo, una conversión forzada documenta esa certeza. Aun así, prefiera as? cuando no esté seguro.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
func barkIfDog(_ a: Animal) {
    guard a is Dog else { return }
    let dog = a as! Dog
    print(dog.bark())
}
barkIfDog(Dog(name: "Rex"))

Comparar as? y as!

as? es seguro y devuelve un opcional; as! fuerza la conversión y provoca un error si falla. Elija uno u otro según el grado de certeza que tenga.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let safe = a as? Dog
let forced = a as! Dog
print(safe?.bark() ?? "nil")
print(forced.bark())

Conversiones forzadas de colecciones

Las conversiones forzadas también funcionan con colecciones completas, como array as! [Dog], pero el mismo riesgo de error se aplica a cada elemento.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let animals: [Animal] = [Dog(name: "Rex"), Dog(name: "Buddy")]
let dogs = animals as! [Dog]
for d in dogs { print(d.bark()) }

Un patrón peligroso

Convertir forzadamente un array que contiene un elemento incorrecto provoca un error. Por eso, en las colecciones mixtas debe usar as? para cada elemento.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let animals: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
// let dogs = animals as! [Dog] // would crash on the Cat
for a in animals {
    if let d = a as? Dog { print(d.bark()) }
}

Desenvolver forzadamente frente a convertir forzadamente

El signo ! de as! es conceptualmente similar a desenvolver forzadamente un opcional: resulta práctico, pero es peligroso si la suposición es incorrecta.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let viaOptional = (a as? Dog)!
let viaForce = a as! Dog
print(viaOptional.name, viaForce.name)

Práctica recomendada

Use as? de forma predeterminada. Reserve as! para los casos en los que un fallo indique un error del programador que quiera detectar de inmediato durante el desarrollo.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
func process(_ a: Animal) -> String {
    if let d = a as? Dog { return d.bark() }
    return "not a dog"
}
print(process(Dog(name: "Rex")))
print(process(Cat(name: "Mia")))

Ejemplo resumido de conversión forzada

Cuando el tipo está verificado, as! resulta claro. Si tiene dudas, la conversión condicional segura es la herramienta adecuada.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let known: Animal = Dog(name: "Rex")
if known is Dog {
    print((known as! Dog).bark())
}

Comprobación rápida

Razone sobre el peligro de las conversiones forzadas.

Resumen: conversión forzada y sus riesgos

Ha aprendido que as! realiza una conversión descendente y desenvuelve el resultado como un tipo no opcional, pero provoca un error si falla; que solo debe usarse cuando tenga la certeza del tipo, normalmente después de una comprobación con is; y que as? sigue siendo la opción predeterminada más segura.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if a is Dog { print((a as! Dog).bark()) } else { print("safe skip") }

Preguntas frecuentes

¿La lección «Conversión forzada con as! y sus riesgos» es gratis?

Sí — el texto completo de «Conversión forzada con as! y sus riesgos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Conversión forzada con as! y sus riesgos»?

Utilice as! solo cuando tenga la certeza de que la conversión funcionará. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Conversión forzada con as! y sus riesgos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Fundamentos de upcasting y downcasting
  2. Conversión condicional con as?
  3. Conversión forzada con as! y sus riesgos
  4. Comprobación de tipos con is
← Volver a Swift Academy