Zaktualizowano dla Swift 5.1
Załóżmy, że funkcja rzucania:
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)
}
}
próbować
Masz 2 opcje, gdy próbujesz wywołać funkcję, która może rzucać.
Możesz wziąć odpowiedzialność za obsługę błędów , otaczając połączenie w bloku do-catch:
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)
}
Lub po prostu spróbuj wywołać funkcję i przekaż błąd do następnego wywołującego w łańcuchu wywołań:
func doSomeOtherThing() throws -> Void {
// Not within a do-catch block.
// Any errors will be re-thrown to callers.
let result = try doSomething()
}
próbować!
Co się dzieje, gdy próbujesz uzyskać dostęp do niejawnie rozpakowanego elementu opcjonalnego z zerem w środku? Tak, to prawda, aplikacja ulegnie awarii! To samo dotyczy try! zasadniczo ignoruje łańcuch błędów i deklaruje sytuację „zrób albo zgiń”. Jeśli wywołana funkcja nie zgłosiła żadnych błędów, wszystko idzie dobrze. Ale jeśli się nie powiedzie i wyrzuci błąd, aplikacja po prostu ulegnie awarii .
let result = try! doSomething() // if an error was thrown, CRASH!
próbować?
Nowe słowo kluczowe, które zostało wprowadzone w Xcode 7 beta 6. Zwraca opcjonalne, które rozpakowuje pomyślne wartości i wyłapuje błąd, zwracając nil.
if let result = try? doSomething() {
// doSomething succeeded, and result is unwrapped.
} else {
// Ouch, doSomething() threw an error.
}
Lub możemy użyć strażnika:
guard let result = try? doSomething() else {
// Ouch, doSomething() threw an error.
}
// doSomething succeeded, and result is unwrapped.
Ostatnia uwaga tutaj, używając try?
uwagi, że odrzucasz błąd, który miał miejsce, ponieważ jest on tłumaczony na zero. Użyj try? kiedy koncentrujesz się bardziej na sukcesach i porażkach, a nie na tym, dlaczego coś zawiodło.
Korzystanie z operatora koalescencji?
Możesz użyć operatora koalescencji ?? z próbą? aby podać wartość domyślną w przypadku awarii:
let result = (try? doSomething()) ?? "Default Value"
print(result) // Default Value
let result = try doSomething() // Not within a do-catch block
) ma zostać wywołany z metody zadeklarowanej jakothrows
, prawda? Więc jeślidoSomething()
zawiedzie, to czy też metoda zewnętrzna (z kolei)?try?
with,??
aby umożliwić zdefiniowanie wartości domyślnej w jednej linii:let something:String = (try? whateverIfItThrows()) ?? "Your default value here"