do, try, catch
Parte de la sección Lógica y Flujo del Journey de Swift de Coddy — lección 45 de 56.
La forma completa para manejar errores es 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 va delante de cualquier llamada que lance un error. Si la llamada lanza un error, el control salta al catch correspondiente; de lo contrario, la ejecución continúa después del bloque do.
Múltiples cláusulas catch se ejecutan de arriba a abajo y la primera coincidencia gana, al igual que un switch. El catch simple al final es el que captura todo, casi siempre querrás uno para mantener contento al compilador.
Desafío
FácilDefine un enum ParseError: Error con tres casos: empty, notInteger y negative.
Define una función que lanza errores parsePositive(_ s: String) throws -> Int que:
- Lanza
.emptycuandoseliminando los espacios en blanco está vacío - Lanza
.notIntegercuandosno puede ser analizado comoInt - Lanza
.negativecuando el valor analizado es< 0 - De lo contrario, devuelve el valor analizado
Lee una sola línea de stdin y llama a parsePositive en un bloque do/catch. Imprime:
got: <n>en caso de éxitoerror: empty,error: not integeroerror: negativepara cada caso
Para la entrada 42, la salida es got: 42. Para una línea vacía, es error: empty. Para abc es error: not integer.
Hoja de referencia
El manejo de errores en Swift utiliza do/try/catch. Define errores con un enum que cumpla con Error, marca las funciones que lanzan errores con throws y utiliza throw para lanzar un error:
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 todo
}trydebe preceder a cada llamada que lance un error.- Las cláusulas
catchse comparan de arriba hacia abajo; la primera coincidencia gana. - Un
catchsimple al final actúa como un capturador para todo.
Pruébalo tú mismo
let line = readLine()!
// TODO: enum ParseError; func parsePositive(_:) throws -> Int;
// do/try/catch con tres ramas más la rama por defecto
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Lógica y Flujo
1Strings a fondo
Conteo e índicesMayúsculas, minúsculas y TrimBúsqueda en StringsDividir y unirReemplazo de subcadenasResumen: Validación de usuario4Conjuntos
Crear conjuntosUnión e intersecciónResta y diferencia simétricaSubconjunto y superconjuntoResumen - Filtro de etiquetas7Proyecto - Seguimiento de hábitos
Descripción general del proyectoMarcar como completado10Proyecto - Motor de cuestionarios
Descripción general del proyectoHacer preguntas2Rangos e Intervalos
Cerrados vs. SemiabiertosSaltos (Stride)Métodos de RangosRangos en SwitchResumen - Cuadrícula de calendario5Funciones de orden superior Pt. 1
MapFilterReduceEncadenar map, filter, reduceResumen - Estadísticas de palabras3Diccionarios
Declaración de diccionariosBúsqueda opcionalActualización de diccionariosIteración de diccionariosAgrupación de valoresResumen - Inventario6Funciones de orden superior - Parte 2
compactMapflatMapsorted(by:)Construcción de pipelinesRepaso - Tabla de posiciones9Manejo de errores
throws y Errordo, try, catchtry? y try!Propagación de erroresRepaso - Calculadora segura