Menu
Coddy logo textTech

do, try, catch

Parte da seção Lógica e Fluxo do Journey de Swift da Coddy — lição 45 de 56.

A forma completa para lidar com erros é 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 fica antes de qualquer chamada que lance um erro. Se a chamada lançar um erro, o controle pula para o catch correspondente; caso contrário, a execução continua após o bloco do.

Múltiplas cláusulas catch são executadas de cima para baixo e a primeira correspondência vence, assim como um switch. O catch simples ao final é o "pega-tudo", você quase sempre vai querer um para manter o compilador satisfeito.

challenge icon

Desafio

Fácil

Defina um enum ParseError: Error com três casos: empty, notInteger e negative.

Defina uma função que lança erros parsePositive(_ s: String) throws -> Int que:

  • Lança .empty quando s, após remover os espaços em branco, estiver vazio
  • Lança .notInteger quando s não puder ser analisado como Int
  • Lança .negative quando o valor analisado for < 0
  • Caso contrário, retorna o valor analisado

Leia uma única linha da entrada padrão (stdin) e chame parsePositive em um bloco do/catch. Imprima:

  • got: <n> em caso de sucesso
  • error: empty, error: not integer ou error: negative para cada caso

Para a entrada 42, a saída é got: 42. Para uma linha vazia, é error: empty. Para abc, é error: not integer.

Folha de consulta

O tratamento de erros no Swift utiliza do/try/catch. Defina erros com um enum em conformidade com Error, marque funções que lançam erros com throws e use throw para lançar um erro:

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")        // captura tudo
}
  • try deve preceder cada chamada que lança erro.
  • As cláusulas catch são comparadas de cima para baixo; a primeira correspondência vence.
  • Um catch simples ao final atua como um captura-tudo.

Experimente você mesmo

let line = readLine()!

// TODO: enum ParseError; func parsePositive(_:) throws -> Int;
// do/try/catch com três ramos mais o catch-all
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Lógica e Fluxo