Alguna perspectiva general para agregar a las otras respuestas útiles pero más centradas en los detalles:
En Swift, el signo de exclamación aparece en varios contextos:
- Envoltura forzada:
let name = nameLabel!.text
- Opcionales implícitamente sin envolver:
var logo: UIImageView!
- Fundición forzada:
logo.image = thing as! UIImage
- Excepciones no manejadas:
try! NSJSONSerialization.JSONObjectWithData(data, [])
Cada uno de estos es una construcción de lenguaje diferente con un significado diferente, pero todos tienen tres cosas importantes en común:
1. Los signos de exclamación eluden los controles de seguridad en tiempo de compilación de Swift.
Cuando lo usa !
en Swift, esencialmente dice: "Oye, compilador, sé que cree que podría ocurrir un error aquí, pero sé con total certeza que nunca lo hará".
No todo el código válido cabe en la caja del sistema de tipos de tiempo de compilación de Swift, o la comprobación de tipos estáticos de cualquier idioma, para el caso. Hay situaciones en las que puede probar lógicamente que nunca se producirá un error, pero no puede probarlo al compilador . Es por eso que los diseñadores de Swift agregaron estas características en primer lugar.
Sin embargo, cada vez que usa !
, descarta tener una ruta de recuperación para un error, lo que significa que ...
2. Los puntos de exclamación son posibles accidentes.
Un signo de exclamación también dice: "Hola Swift, estoy tan seguro de que este error nunca puede ocurrir que es mejor que bloquees toda mi aplicación que codificar una ruta de recuperación para ella".
Esa es una afirmación peligrosa. Se puede ser la correcta: en clave de misión crítica en la que han pensado mucho sobre invariantes de su código, puede ser que la salida falsa es peor que un accidente.
Sin embargo, cuando veo !
en la naturaleza, rara vez se usa con tanta atención. En cambio, con demasiada frecuencia significa, "este valor era opcional y realmente no pensé demasiado sobre por qué podría ser nulo o cómo manejar adecuadamente esa situación, pero agregarlo !
lo compiló ... así que mi código es correcto, ¿verdad?"
Cuidado con la arrogancia del signo de exclamación. En lugar…
3. Los puntos de exclamación se usan mejor con moderación.
Cada una de estas !
construcciones tiene una ?
contraparte que te obliga a lidiar con el caso de error / nulo:
- Desenvoltura condicional:
if let name = nameLabel?.text { ... }
- Opcionales:
var logo: UIImageView?
- Lanzamientos condicionales:
logo.image = thing as? UIImage
- Excepciones sin falla:
try? NSJSONSerialization.JSONObjectWithData(data, [])
Si tiene la tentación de usar !
, siempre es bueno considerar cuidadosamente por qué no lo está usando ?
. ¿Bloquear su programa es realmente la mejor opción si la !
operación falla? ¿Por qué ese valor es opcional / no disponible?
¿Existe una ruta de recuperación razonable que su código podría tomar en el caso de nulo / error? Si es así, codifíquelo.
Si no puede ser nulo, si el error nunca puede suceder, ¿hay alguna forma razonable de reelaborar su lógica para que el compilador lo sepa? Si es así, hazlo; su código será menos propenso a errores.
Hay momentos en que no hay una forma razonable de manejar un error, y simplemente ignorar el error, y así proceder con datos incorrectos, sería peor que estrellarse. Esos son los momentos para usar el desenvolvimiento forzado.
Periódicamente busco en toda mi base de código !
y audito cada uso del mismo. Muy pocos usos resisten el escrutinio. (Al escribir estas líneas, todo el marco de Siesta tiene exactamente dos instancias de él).
Eso no quiere decir que nunca debe usarlo !
en su código, solo que debe usarlo conscientemente y nunca hacerlo la opción predeterminada.