이번 편의 목표: 빈 제목처럼 실패한 입력을 오류로 던지고, 호출자가 do와 catch로 처리하게 합니다.
실패할 수 있는 함수는 throws를 붙입니다. 던지는 값은 Error 프로토콜을 채택합니다. 호출부는 try를 적어야 그 함수를 호출할 수 있습니다. try를 빠뜨리면 컴파일이 멈춥니다.
enum LibraryError: Error {
case emptyTitle
case nonPositivePrice
}
func register(title: String, price: Int) throws -> String {
if title.isEmpty {
throw LibraryError.emptyTitle
}
if price <= 0 {
throw LibraryError.nonPositivePrice
}
return "\(title) \(price)"
}
do {
let registered = try register(title: "개미", price: 12000)
print(registered)
try register(title: "", price: 12000)
} catch LibraryError.emptyTitle {
print("제목이 필요합니다.")
} catch {
print("등록에 실패했습니다.")
}첫 등록은 개미 12000을 출력합니다. 둘째 호출은 빈 제목이라 emptyTitle로 들어가 제목이 필요합니다. 를 출력합니다. catch가 그 오류를 받으면 프로그램은 멈추지 않고 다음 줄로 진행할 수 있습니다. 위의 do 블록은 둘째 호출에서 빠져나가므로, 그 뒤에 코드를 더 넣어도 둘째 호출이 실패한 뒤에는 실행되지 않습니다.
가격만 잘못된 경우는 마지막 catch로 갑니다. 케이스마다 문장이 달라야 하면 catch LibraryError.nonPositivePrice를 따로 둡니다.
호출부가 오류를 처리하지 않고 자신의 호출자에게 넘길 수도 있습니다. 그 함수도 throws를 붙이고 try만 적습니다. 옵셔널로 바꾸고 싶으면 try?를 씁니다. 성공하면 값이 들어 있고 실패하면 nil입니다. 실패 이유는 사라지므로, 이유를 보여 줄 화면에서는 do와 catch를 유지합니다.
직접 해 보기
가격 0인 등록을 호출해 nonPositivePrice 분기의 문장이 출력되는지 확인하세요.
해설
price <= 0 조건이 먼저 던집니다. catch LibraryError.nonPositivePrice에서 가격은 1원 이상이어야 합니다. 같은 문장을 출력하면 그 케이스가 선택된 것입니다. 빈 제목과 동시에 있으면 함수에 먼저 적은 제목 검사가 먼저 던집니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.