Menu
Coddy logo textTech

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ć.

challenge icon

Wyzwanie

Średni

Zbuduj 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 powodzenia
  • negative, gdy zgłoszono błąd w parseSafe
  • too big, gdy zgłoszono błąd w capStrict

Dla danych wejściowych 10,-1,200,42 wynikiem jest:

ok: 10
negative
too big
ok: 42

Spró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
quiz iconSprawdź się

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

Poćwicz samodzielnie: Edytor online Swift