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.
Desafio
FácilDefina 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
.emptyquandos, após remover os espaços em branco, estiver vazio - Lança
.notIntegerquandosnão puder ser analisado comoInt - Lança
.negativequando 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 sucessoerror: empty,error: not integerouerror: negativepara 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
}trydeve preceder cada chamada que lança erro.- As cláusulas
catchsão comparadas de cima para baixo; a primeira correspondência vence. - Um
catchsimples 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
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
1Strings a Fundo
Contagem e ÍndicesCase e TrimBusca em StringsDivisão e JunçãoSubstituindo SubstringsRecapitulação - Verificação de Nome de Usuário4Conjuntos
Criando ConjuntosUnião e InterseçãoSubtração e Diferença SimétricaSubconjunto e SuperconjuntoRecapitulação - Filtro de Tags7Projeto - Monitor de Hábitos
Visão Geral do ProjetoMarcar como Concluído10Projeto - Mecanismo de Quiz
Visão Geral do ProjetoFazer Perguntas2Intervalos e Strides
Fechado vs Meio-AbertoStrideMétodos de IntervaloIntervalos no SwitchRecapitulação - Grade de Calendário5Funções de Ordem Superior Parte 1
MapFilterReduceEncadeando map, filter, reduceRecapitulação - Estatísticas de Palavras3Dicionários
Declarando DicionáriosBusca OpcionalAtualizando DicionáriosIterando DicionáriosAgrupando ValoresRecapitulação - Inventário6Funções de Ordem Superior Parte 2
compactMapflatMapsorted(by:)Construindo PipelinesRecapitulação - Leaderboard9Tratamento de Erros
throws e Errordo, try, catchtry? e try!Propagando ErrosRecapitulação - Calculadora Segura