protocol - swift<<
¿Cuál es la diferencia entre "as?", "As!" Y "as"? (3)
as
En Swift 1.2 y
versiones
posteriores,
as
que solo se puede usar para la
conversión
(o desambiguación) y
la coincidencia de patrones
:
// ''as'' for disambiguation
let width = 42 as CGFloat
let block = { x in x+1 } as Double -> Double
let something = 3 as Any? // optional wrapper can also be added with ''as''
// ''as'' for pattern matching
switch item {
case let obj as MyObject:
// this code will be executed if item is of type MyObject
case let other as SomethingElse:
// this code will be executed if item is of type SomethingElse
...
}
as?
El operador de conversión
condicional
as?
intenta realizar una conversión, pero devuelve
nil
si no puede.
Por lo tanto, su resultado es opcional.
let button = someView as? UIButton // button''s type is ''UIButton?''
if let label = (superview as? MyView)?.titleLabel {
// ...
}
as!
El
as!
El operador es para conversión de tipo
forzado
.
Utilice la forma forzada del operador de conversión de tipos (
as!
) Solo cuando esté seguro de que el downcast siempre tendrá éxito. Esta forma del operador activará un error de tiempo de ejecución si intenta bajar a un tipo de clase incorrecto.
// ''as!'' for forced conversion.
// NOT RECOMMENDED.
let buttons = subviews as! [UIButton] // will crash if not all subviews are UIButton
let label = subviews.first as! UILabel
Antes de actualizar a Swift 1.2, podría escribir la siguiente línea:
if let width = imageDetails["width"] as Int?
Ahora me obliga a escribir esta línea:
if let width = imageDetails["width"] as! Int?
Mi pregunta es, si me veo obligado a escribirlo como se indica arriba, ¿no podría simplemente escribir el código a continuación y haría lo mismo? ¿Me daría el mismo resultado en todos los valores de imageDetails?
if let width = imageDetails["width"] as Int
El idioma correcto que debe hacer exactamente lo que quieres (en todas las versiones de Swift al menos hasta e incluyendo 1.2) es el
as?
elenco opcional.
if let width = imageDetails["width"] as? Int
La conversión opcional devuelve un opcional (Int? En este caso) y se prueba en tiempo de ejecución. Su código original probablemente forzó una conversión al tipo opcional.
La palabra clave as solía hacer tanto upcasts como downcasts:
// Before Swift 1.2
var aView: UIView = someView()
var object = aView as NSObject // upcast
var specificView = aView as UITableView // downcast
El upcast, que pasa de una clase derivada a una clase base, se puede verificar en tiempo de compilación y nunca fallará.
Sin embargo, las descargas pueden fallar ya que no siempre puede estar seguro de la clase específica. Si tiene una UIView, es posible que sea una UITableView o tal vez una UIButton. Si su downcast va al tipo correcto, ¡genial! Pero si especificas el tipo incorrecto, obtendrás un error de tiempo de ejecución y la aplicación se bloqueará.
En Swift 1.2, los downcasts deben ser opcionales con as? o "forzado a fallar" con as !. Si estás seguro del tipo, ¡puedes forzar el lanzamiento con un as! similar a cómo usaría un opcional sin envoltura implícita:
// After Swift 1.2
var aView: UIView = someView()
var tableView = aView as! UITableView
¡El signo de exclamación deja absolutamente claro que sabes lo que estás haciendo y que existe la posibilidad de que las cosas salgan terriblemente mal si accidentalmente has mezclado tus tipos!
Como siempre, como? con encuadernación opcional es el camino más seguro:
// This isn''t new to Swift 1.2, but is still the safest way
var aView: UIView = someView()
if let tableView = aView as? UITableView {
// do something with tableView
}
Obtuve esto de un sitio: SOURCE