Przekazywanie błędów
Część sekcji Logika i przepływ programu ścieżki Swift w Coddy. Lekcja 47 z 56.
Funkcja zgłaszająca błędy może wywoływać inne funkcje zgłaszające błędy. Błąd automatycznie propaguje się do najbliższej konstrukcji do/catch, bez potrzeby ręcznego ponownego zgłaszania.
enum AuthError: Error { case badUser, badPass }
func loadUser(_ name: String) throws -> String {
if name.isEmpty { throw AuthError.badUser }
return name
}
func login(_ name: String, _ pass: String) throws -> String {
let u = try loadUser(name) // przekazuje błąd dalej
if pass.count < 4 { throw AuthError.badPass }
return "hello \(u)"
}
do {
print(try login("", "abcd"))
} catch AuthError.badUser {
print("missing user")
} catch AuthError.badPass {
print("weak password")
}Czytaj od góry do dołu: login wywołuje loadUser z użyciem try. Jeśli loadUser zgłosi wyjątek, błąd omija ciało funkcji login i trafia do zewnętrznego bloku catch. Każdy krok zapisujesz tak, aby szybko kończył działanie w razie błędu, i pozwalasz wywołującemu zdecydować, co zrobić.
Wyzwanie
ŚredniZbuduj mały potok złożony z dwóch kroków zgłaszających błędy.
Zdefiniuj StepError: Error z dwoma przypadkami: negative, tooBig.
Zdefiniuj parseSafe(_ s: String) throws -> Int: zgłasza .negative, gdy sparsowana liczba całkowita jest mniejsza niż 0, w przeciwnym razie ją zwraca. (Załóż, że dane wejściowe można sparsować — obsłużono to gdzie indziej.)
Zdefiniuj capStrict(_ n: Int) throws -> Int: zgłasza .tooBig, gdy n > 100, w przeciwnym razie zwraca n.
Zdefiniuj processStep(_ s: String) throws -> Int, która wywołuje najpierw parseSafe, a potem capStrict, pozwalając na propagację dowolnego błędu.
Odczytaj jeden wiersz danych wejściowych: listę ciągów znaków oddzielonych przecinkami. Dla każdego wywołaj processStep w bloku do/catch i wypisz jeden wiersz:
ok: <n>w przypadku powodzenianegative, gdy zgłoszono błąd wparseSafetoo big, gdy zgłoszono błąd wcapStrict
Dla danych wejściowych 10,-1,200,42 wynikiem jest:
ok: 10
negative
too big
ok: 42Spróbuj swoich sił
let parts = readLine()!.components(separatedBy: ",")
// TODO: enum StepError; parseSafe; capStrict; processStep;
// dla każdego elementu wykonaj do/try processStep, obsłuż każdą gałąź przez catch i wypisz wynik
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i przepływ programu
1Dogłębnie o ciągach znaków
Liczba i indeksyWielkość liter i usuwanie białych znakówWyszukiwanie w ciągach znakówDzielenie i łączenieZastępowanie podciągówPodsumowanie — sprawdzanie nazwy użytkownika4Zbiory
Tworzenie zbiorówSuma i część wspólnaRóżnica i różnica symetrycznaPodzbiór i nadzbiórPowtórka — filtr tagów7Projekt – Śledzenie nawyków
Przegląd projektuOznacz jako wykonane10Projekt — silnik quizów
Przegląd projektuZadawanie pytań2Zakresy i kroki
Zakresy domknięte i półotwarteKrokMetody zakresówZakresy w instrukcji switchPowtórka — siatka kalendarza5Funkcje wyższego rzędu, część 1
MapFilterReduceŁączenie map, filter i reducePodsumowanie – statystyki słów3Słowniki
Deklarowanie słownikówWyszukiwanie opcjonalneAktualizowanie słownikówIterowanie po słownikachGrupowanie wartościPodsumowanie – inwentarz6Funkcje wyższego rzędu, cz. 2
compactMapflatMapsorted(by:)Tworzenie potokówPowtórzenie – tabela wyników9Obsługa błędów
throws i Errordo, try, catchtry? i try!Przekazywanie błędówPowtórka — bezpieczny kalkulatorPoćwicz samodzielnie: Edytor online Swift