Actualizado para Swift 5.1
Asuma la siguiente función de lanzamiento:
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)
}
}
tratar
Tiene 2 opciones cuando intenta llamar a una función que puede lanzar.
Puede asumir la responsabilidad de manejar los errores rodeando su llamada dentro de un bloque de captura automática:
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)
}
O simplemente intente llamar a la función y pasar el error a la siguiente persona que llama en la cadena de llamadas:
func doSomeOtherThing() throws -> Void {
// Not within a do-catch block.
// Any errors will be re-thrown to callers.
let result = try doSomething()
}
¡tratar!
¿Qué sucede cuando intenta acceder a una opción implícitamente desenvuelta con un cero dentro de ella? Sí, es cierto, la aplicación se CRASH! Lo mismo ocurre con el intento! Básicamente ignora la cadena de error y declara una situación de "hacer o morir". Si la función llamada no arrojó ningún error, todo va bien. Pero si falla y arroja un error, su aplicación simplemente se bloqueará .
let result = try! doSomething() // if an error was thrown, CRASH!
¿tratar?
Una nueva palabra clave que se introdujo en Xcode 7 beta 6. Devuelve un opcional que desenvuelve valores exitosos y detecta errores al devolver nil.
if let result = try? doSomething() {
// doSomething succeeded, and result is unwrapped.
} else {
// Ouch, doSomething() threw an error.
}
O podemos usar guardia:
guard let result = try? doSomething() else {
// Ouch, doSomething() threw an error.
}
// doSomething succeeded, and result is unwrapped.
Una nota final aquí, al usar la try?
nota de que está descartando el error que ocurrió, ya que se traduce en cero. Usar intento? cuando te enfocas más en los éxitos y los fracasos, no en por qué fallaron las cosas.
¿Usando el operador de fusión?
¿Puedes usar el operador de fusión? con intento? para proporcionar un valor predeterminado en caso de falla:
let result = (try? doSomething()) ?? "Default Value"
print(result) // Default Value
let result = try doSomething() // Not within a do-catch block
) se llamará desde un método que se declare comothrows
, ¿verdad? Entonces, sidoSomething()
falla, ¿también lo hace el método externo (a su vez)?try?
con,??
por lo que le permitiría definir un valor predeterminado en una línea:let something:String = (try? whateverIfItThrows()) ?? "Your default value here"