essayer essayer! et essayez? quelle est la différence et quand les utiliser?

172

Dans Swift 2.0 , Apple a introduit une nouvelle façon de gérer les erreurs (do-try-catch). Et il y a quelques jours, dans la bêta 6, un mot-clé encore plus récent a été introduit ( try?). Aussi, je savais que je peux utiliser try!. Quelle est la différence entre les 3 mots clés et quand les utiliser?

Abdurrahman
la source

Réponses:

316

Mis à jour pour Swift 5.1

Supposons la fonction de lancement suivante:

enum ThrowableError: Error {

    case badError(howBad: Int)
}

func doSomething(everythingIsFine: Bool = false) throws -> String {

  if everythingIsFine {
      return "Everything is ok"
  } else {
      throw ThrowableError.badError(howBad: 4)
  }
}

essayer

Vous avez 2 options lorsque vous essayez d'appeler une fonction qui peut lancer.

Vous pouvez prendre la responsabilité de gérer les erreurs en entourant votre appel dans un bloc do-catch:

do {
    let result = try doSomething()
}
catch ThrowableError.badError(let howBad) {
    // Here you know about the error
    // Feel free to handle or to re-throw

    // 1. Handle
    print("Bad Error (How Bad Level: \(howBad)")

    // 2. Re-throw
    throw ThrowableError.badError(howBad: howBad)
}

Ou essayez simplement d'appeler la fonction et transmettez l'erreur au prochain appelant dans la chaîne d'appels:

func doSomeOtherThing() throws -> Void {    
    // Not within a do-catch block.
    // Any errors will be re-thrown to callers.
    let result = try doSomething()
}

essayer!

Que se passe-t-il lorsque vous essayez d'accéder à un optionnel implicitement déballé avec un nul à l'intérieur? Oui, c'est vrai, l'application CRASH! Il en va de même pour essayer! il ignore fondamentalement la chaîne d'erreur et déclare une situation «faire ou mourir». Si la fonction appelée n'a généré aucune erreur, tout se passe bien. Mais s'il échoue et génère une erreur, votre application se bloque simplement .

let result = try! doSomething() // if an error was thrown, CRASH!

essayer?

Un nouveau mot-clé qui a été introduit dans Xcode 7 beta 6. Il renvoie une option qui déballe les valeurs réussies et intercepte l'erreur en renvoyant nil.

if let result = try? doSomething() {
    // doSomething succeeded, and result is unwrapped.
} else {
    // Ouch, doSomething() threw an error.
}

Ou nous pouvons utiliser la garde:

guard let result = try? doSomething() else {
    // Ouch, doSomething() threw an error.
}
// doSomething succeeded, and result is unwrapped.

Une dernière note ici, en utilisant la try?note que vous supprimez l'erreur qui a eu lieu, car elle est traduite par zéro. Utilisez try? lorsque vous vous concentrez davantage sur les succès et les échecs, pas sur les raisons pour lesquelles les choses ont échoué.

Utilisation de l'opérateur de coalescence ??

Vous pouvez utiliser l'opérateur de fusion ?? avec essayer? pour fournir une valeur par défaut en cas d'échec:

let result = (try? doSomething()) ?? "Default Value"
print(result) // Default Value
Abdurrahman
la source
Votre deuxième exemple de code ( let result = try doSomething() // Not within a do-catch block) doit être appelé à partir d'une méthode déclarée comme throws, non? Donc, en cas d' doSomething()échec, la méthode externe aussi (à son tour)?
Nicolas Miari
Vieux fil et tout, mais j'ai trouvé qu'aujourd'hui (Swift 4, Xcode 9.1) essayez? ne déroule pas automatiquement le résultat. Cela laisse simplement une option normale pour que vous puissiez déballer manuellement. Je ne sais pas si cela a changé depuis Swift 2/3 mais c'est par la documentation: developer.apple.com/library/content/documentation/Swift/… (voir Conversion d'erreurs en valeurs facultatives ). Excellente explication d'essayer btw.
the_dude_abides
1
dans Swift 4, essayez? ne supprime pas les appels non aux fonctions de lancement qui se produisent dans les expressions 'try' de mon projet.
aznelite89
7
Vous pouvez également utiliser try?avec ??pour vous permettre de définir une valeur par défaut sur une seule ligne:let something:String = (try? whateverIfItThrows()) ?? "Your default value here"
itMaxence