Menu
Coddy logo textTech

do, try, catch

Fait partie de la section Logique et Flux du Journey Swift de Coddy — leçon 45 sur 56.

La forme complète pour la gestion des erreurs est do/try/catch :

enum DivError: Error { case byZero }

func divide(_ a: Int, _ b: Int) throws -> Int {
    if b == 0 { throw DivError.byZero }
    return a / b
}

do {
    let r = try divide(10, 2)
    print(r)                      // 5
} catch DivError.byZero {
    print("can't divide by zero")
} catch {
    print("unknown error")
}

try se place devant tout appel susceptible de lever une erreur. Si l'appel lève une erreur, le contrôle passe au bloc catch correspondant ; sinon, l'exécution se poursuit après le bloc do.

Plusieurs clauses catch s'exécutent de haut en bas et la première correspondance l'emporte, tout comme un switch. Le catch simple à la fin est la clause générique, vous en voudrez presque toujours une pour satisfaire le compilateur.

challenge icon

Défi

Facile

Définissez une énumération ParseError: Error avec trois cas : empty, notInteger et negative.

Définissez une fonction lançant une erreur parsePositive(_ s: String) throws -> Int qui :

  • Lance .empty lorsque s, une fois les espaces supprimés, est vide
  • Lance .notInteger lorsque s ne peut pas être analysé comme un Int
  • Lance .negative lorsque la valeur analysée est < 0
  • Sinon, renvoie la valeur analysée

Lisez une seule ligne depuis stdin et appelez parsePositive dans un bloc do/catch. Affichez :

  • got: <n> en cas de succès
  • error: empty, error: not integer ou error: negative pour chaque cas

Pour l'entrée 42, la sortie est got: 42. Pour une ligne vide, c'est error: empty. Pour abc, c'est error: not integer.

Aide-mémoire

La gestion des erreurs en Swift utilise do/try/catch. Définissez les erreurs avec une énumération conforme à Error, marquez les fonctions qui lèvent des erreurs avec throws, et utilisez throw pour lever une erreur :

enum DivError: Error { case byZero }

func divide(_ a: Int, _ b: Int) throws -> Int {
    if b == 0 { throw DivError.byZero }
    return a / b
}

do {
    let r = try divide(10, 2)
    print(r)                      // 5
} catch DivError.byZero {
    print("can't divide by zero")
} catch {
    print("unknown error")        // capture tout
}
  • try doit précéder chaque appel susceptible de lever une erreur.
  • Les clauses catch sont comparées de haut en bas ; la première correspondance l'emporte.
  • Un catch simple à la fin fait office de capture tout.

Essayez vous-même

let line = readLine()!

// À FAIRE : enum ParseError ; func parsePositive(_:) throws -> Int ;
// do/try/catch avec trois branches plus le cas général
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Logique et Flux