오류표현
Error 프로토콜과 (주로) 열거형을 통해서 오류를 표현한다.
enum 오류종류이름: Error {
case 종류1
case 종류2
case 종류3
// . . .
}
// 자판기 동작 오류의 종류를 표현한 VendingMachineError 열거형
enum VendingMachineError: Error {
case invalidInput
case insufficientFunds(moneyNeeded: Int)
case outOfStock
}
// 함수에서 발생한 오류 던지기
// 자판기 동작 도중 발생한 오류 던지기
// 오류 발생의 여지가 있는 메서드는 throws 를 사용하여
// 오류를 내포하는 함수임을 표시한다.
class VendingMachine {
let itemPrice: Int = 100
var itemCount: Int = 5
var deposited: Int = 0
// 돈 받기 메서드
func receiveMoney(_ money: Int) throws {
// 입력한 돈이 0 이하면 오류를 던진다.
guard money > 0 else {
throw VendingMachineError.invalidInput
}
// 오류가 없으면 정상처리를 한다.
self.deposited += money
print("\(money)원 받음")
}
// 물건 팔기 메서드
func vend(numberOfItems numberOfItemsToVend: Int) throws -> String {
// 원하는 아이템의 수량이 잘못 입력되었으면 오류를 던진다.
guard numberOfItemsToVend > 0 else {
throw VendingMachineError.invalidInput
}
// 구매하려는 수량보다 미리 넣어둔 돈이 적으면 오류를 던진다.
guard numberOfItemsToVend * itemPrice <= deposited else {
let moneyNeeded: Int
moneyNeeded = numberOfItemsToVend * itemPrice - deposited
throw VendingMachineError.insufficientFunds(moneyNeeded: moneyNeeded)
}
// 구매하려는 수량보다 요구하는 수량이 많으면 오류를 던진다.
guard itemCount >= numberOfItemsToVend else {
throw VendingMachineError.outOfStock
}
// 오류가 없으면 정상처리를 한다.
let totalPrice = numberOfItemsToVend * itemPrice
self.deposited -= totalPrice
self.itemCount -= numberOfItemsToVend
return "\(numberOfItemsToVend)개 제공함"
}
}
// 자판기 인스턴스
let machine: VendingMachine = VendingMachine()
// 판매 결과를 전달받을 변수
var result: String?
// 오류처리
// 오류발생의 여지가 있는 throws 함수(메서드)는
// try 를 사용하여 호출해야 한다.
// try, try?, try!
// do-catch
// 오류발생의 여지가 있는 throws 함수(메서드)는
// do-catch 구문을 활용하여
// 오류발생에 대비한다.
do {
try machine.receiveMoney(0)
} catch VendingMachineError.invalidInput {
print("오류")
} catch VendingMachineError.insufficientFunds(let moneyNeeded) {
print("오류")
} catch VendingMachineError.outOfStock {
print("오류")
}
// 위 아래 같음.
do {
try machine.receiveMoney(300)
} catch {
switch error {
case VendingMachineError.invalidInput:
print("오류")
case VendingMachineError. insufficientFunds(let moneyNeeded):
print("오류")
case VendingMachineError. outOfStock:
print("오류")
}
}
// 간결하게 표현 가능
do {
result try machine.vend(numberOfItems: 4)
} catch {
print(error)
}
// 오류 신경쓰지 않겠다는 것임.
do {
result = try.machine.vend(numberOfItems: 4)
}
// try?
// 별도의 오류처리 결과를 통보받지 않고
// 오류가 발생했으면 결과값을 nil로 돌려받을 수 있다.
// 정상동작 후에는 옵셔널 타입으로 정상 반환값을 돌려 받는다.
result = try? machine.vend(numberOfItems: 2)
result // Optional("2개 제공함")
result = try? machine.vend(numberOfItems: 2)
result // nil
// try!
// 오류가 발생하지 않을 것이라는 강력한 확신을 가질 때
// try! 를 사용하면 정상동작 후에 바로 결과값을 돌려 받는다.
// 오류가 발생하면 런타임 오류가 발생하여
// 애플리케이션 동작이 중지된다.
result = try! machine.vend(numberOfItems: 1)
result // 1개 제공함
// result = try! machine.vend(numberOfItems: 1) - 에러 발생!!
'# 02 > Swift' 카테고리의 다른 글
[Swift] 주석, 타입 별칭, 튜플 (0) | 2020.06.05 |
---|---|
[Swift] 고차함수 (0) | 2020.06.05 |
[Swift] 익스텐션 (0) | 2020.06.05 |
[Swift] 프로토콜 (0) | 2020.06.05 |
[Swift] assert와 guard (0) | 2020.06.05 |