web-dev-qa-db-fra.com

Quelle est la différence entre "as?", "As!" Et "as"?

Avant de passer à Swift 1.2, je pouvais écrire la ligne suivante:

if let width = imageDetails["width"] as Int?

Maintenant, cela m'oblige à écrire cette ligne:

if let width = imageDetails["width"] as! Int?

Ma question est, si je suis obligé de l'écrire comme ci-dessus, ne pourrais-je pas simplement écrire le code ci-dessous et cela ferait la même chose? Cela me donnerait-il le même résultat dans toutes les valeurs de imageDetails?

if let width = imageDetails["width"] as Int
52
Alex

Le mot-clé as utilisé pour effectuer des montées et des descentes:

// Before Swift 1.2
var aView: UIView = someView()

var object = aView as NSObject // upcast 

var specificView = aView as UITableView // downcast

L'upcast, passant d'une classe dérivée à une classe de base, peut être vérifié au moment de la compilation et n'échouera jamais.

Cependant, les downcasts peuvent échouer car vous ne pouvez pas toujours être sûr de la classe spécifique. Si vous avez une UIView, il est possible que ce soit une UITableView ou peut-être un UIButton. Si votre downcast va au bon type - super! Mais si vous spécifiez le mauvais type, vous obtiendrez une erreur d'exécution et l'application se bloquera.

Dans Swift 1.2, les downcasts doivent être optionnels avec as? Ou "forcés disponibles" avec as !. Si vous êtes sûr du type, vous pouvez forcer le cast avec as! Similaire à comment vous utiliseriez une option implicitement dépliée:

// After Swift 1.2
var aView: UIView = someView()

var tableView = aView as! UITableView

Le point d'exclamation indique clairement que vous savez ce que vous faites et qu'il y a une chance que les choses tournent mal si vous avez accidentellement mélangé vos types!

Comme toujours, comme? avec une reliure optionnelle est le moyen le plus sûr:

// 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
}

J'ai obtenu ceci d'un site: SOURCE

66
Eendje

as

Dans Swift 1.2 et versions ultérieures, as ne peut être utilisé que pour upcasting (ou désambiguïsation) et correspondance de modèle :

// '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?

L'opérateur conditionnel conditionnel as? essaie d'effectuer une conversion, mais renvoie nil s'il ne le peut pas. Son résultat est donc facultatif.

let button = someView as? UIButton  // button's type is 'UIButton?'

if let label = (superview as? MyView)?.titleLabel {
    // ...
}

as!

Le as! L'opérateur est pour la conversion de type forcé .

Utilisez la forme forcée de l'opérateur de transtypage de type (as!) uniquement lorsque vous êtes sûr que le downcast réussira toujours. Cette forme de l'opérateur déclenchera un erreur d'exécution si vous essayez de rétrograder vers un type de classe incorrect.

// '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
40
jtbandes

L'idiome correct qui devrait faire exactement ce que vous voulez (dans toutes les versions de Swift au moins jusqu'à 1.2 inclus)) est le as? fonte facultative.

if let width = imageDetails["width"] as? Int

La conversion facultative renvoie une option (Int? Dans ce cas) et est testée au moment de l'exécution. Votre code d'origine a probablement forcé une conversion vers le type facultatif.

0
Joseph Lord