do, try, catch
Teil des Abschnitts Logik & Kontrollfluss der Swift-Journey von Coddy — Lektion 45 von 56.
Die vollständige Form zur Fehlerbehandlung ist 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 steht vor jedem Aufruf, der einen Fehler auslösen kann. Wenn der Aufruf einen Fehler auslöst, springt die Steuerung zum passenden catch; andernfalls wird die Ausführung hinter dem do-Block fortgesetzt.
Mehrere catch-Blöcke werden von oben nach unten abgearbeitet und der erste Treffer gewinnt, genau wie bei einem switch. Der einfache catch am Ende ist der Auffangblock (catch-all); man möchte fast immer einen haben, um den Compiler zufriedenzustellen.
Aufgabe
EinfachDefiniere ein Enum ParseError: Error mit drei Fällen: empty, notInteger und negative.
Definiere eine throwing Funktion parsePositive(_ s: String) throws -> Int, die:
.emptywirft, wennsnach dem Entfernen von Leerzeichen leer ist.notIntegerwirft, wennsnicht alsIntgeparst werden kann.negativewirft, wenn der geparste Wert< 0ist- Andernfalls den geparsten Wert zurückgibt
Lies eine einzelne Zeile von stdin und rufe parsePositive in einem do/catch-Block auf. Gib Folgendes aus:
got: <n>bei Erfolgerror: empty,error: not integerodererror: negativefür den jeweiligen Fall
Für die Eingabe 42 ist die Ausgabe got: 42. Für eine leere Zeile ist sie error: empty. Für abc ist sie error: not integer.
Spickzettel
Swift-Fehlerbehandlung verwendet do/try/catch. Definieren Sie Fehler mit einem Enum, das Error entspricht, markieren Sie werfende Funktionen mit throws und verwenden Sie throw, um einen Fehler auszulösen:
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") // fängt alles ab
}trymuss jedem werfenden Aufruf vorangestellt werden.catch-Blöcke werden von oben nach unten abgeglichen; der erste Treffer gewinnt.- Ein einfaches
catcham Ende fungiert als Auffangbecken für alle Fehler.
Probier es selbst
let line = readLine()!
// TODO: enum ParseError; func parsePositive(_:) throws -> Int;
// do/try/catch mit drei Zweigen plus dem Catch-all
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik & Kontrollfluss
1Strings im Detail
Zählen und IndizesGroß-/Kleinschreibung und TrimmenSuchen in StringsTeilen und ZusammenfügenTeilstrings ersetzenWiederholung – Benutzernamen-Check4Mengen
Mengen erstellenVereinigung und SchnittmengeDifferenz und symmetrische DifferenzTeilmenge und ObermengeRückblick – Tag-Filter7Projekt - Habit Tracker
ProjektübersichtAls erledigt markieren2Bereiche & Schrittweiten
Geschlossen vs. halboffenSchrittweiteRange-MethodenRanges in SwitchRückblick – Kalender-Grid5Funktionen höherer Ordnung Teil 1
MapFilterReduceVerkettung von map, filter, reduceRückblick – Wortstatistiken3Dictionaries
Dictionaries deklarierenOptionaler LookupDictionaries aktualisierenÜber Dictionaries iterierenWerte gruppierenZusammenfassung – Inventar6Funktionen höherer Ordnung Teil 2
compactMapflatMapsorted(by:)Pipelines erstellenZusammenfassung – Bestenliste9Fehlerbehandlung
throws und Errordo, try, catchtry? und try!Fehler weitergebenZusammenfassung – Sicherer Taschenrechner