do, try, catch
Coddy Swift 여정의 로직 및 흐름 섹션에 포함된 레슨 — 56개 중 45번째.
에러 처리를 위한 전체 형식은 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는 에러를 던지는 모든 호출 앞에 위치합니다. 호출이 에러를 던지면 제어 흐름이 일치하는 catch로 이동하며, 그렇지 않으면 do 블록 이후로 실행이 이어집니다.
여러 개의 catch 절은 위에서 아래로 실행되며 switch 문과 마찬가지로 첫 번째로 일치하는 것이 선택됩니다. 마지막에 있는 아무런 조건이 없는 catch는 모든 예외를 처리하는(catch-all) 역할을 하며, 컴파일러를 만족시키기 위해 거의 항상 하나를 포함하는 것이 좋습니다.
챌린지
쉬움세 가지 케이스 empty, notInteger, negative를 가진 열거형 ParseError: Error를 정의하세요.
다음을 수행하는 에러를 던지는(throwing) 함수 parsePositive(_ s: String) throws -> Int를 정의하세요:
- 공백을 제거한
s가 비어있을 때.empty를 던집니다. s를Int로 파싱할 수 없을 때.notInteger를 던집니다.- 파싱된 값이
< 0일 때.negative를 던집니다. - 그렇지 않으면 파싱된 값을 반환합니다.
stdin에서 한 줄을 읽고 do/catch 블록 내에서 parsePositive를 호출하세요. 다음을 출력하세요:
- 성공 시
got: <n> - 각 케이스에 대해
error: empty,error: not integer, 또는error: negative
입력이 42인 경우 출력은 got: 42입니다. 빈 줄인 경우 error: empty입니다. abc인 경우 error: not integer입니다.
치트 시트
Swift 에러 처리는 do/try/catch를 사용합니다. Error 프로토콜을 준수하는 열거형(enum)으로 에러를 정의하고, 에러를 던지는 함수는 throws로 표시하며, throw를 사용하여 에러를 발생시킵니다:
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는 모든 에러를 던지는 호출 앞에 위치해야 합니다.catch절은 위에서 아래로 매칭되며, 첫 번째로 일치하는 것이 실행됩니다.- 마지막에 있는 빈
catch는 모든 에러를 처리하는 역할을 합니다.
직접 해보기
let line = readLine()!
// TODO: enum ParseError; func parsePositive(_:) throws -> Int;
// 세 개의 분기와 모든 예외를 처리하는 catch-all이 포함된 do/try/catch
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.