
// 자판기 동작 오류의 종류를 표현한 VendingMachineError 열거형
enum VendingMachineError: Error {
// 잘못된 입력을 나타내는 오류
case invalidInput
// 돈이 부족함을 나타내는 오류 (부족한 금액을 포함)
case insufficientFunds(moneyNeeded: Int)
// 재고가 부족함을 나타내는 오류
case outOfStock
}
// 자판기 클래스
class VendingMachine {
let itemPrice: Int = 100 // 아이템 가격
var itemCount: Int = 5 // 아이템 수량
var deposited: Int = 5 // 투입된 돈
// 돈 받기 메서드
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 = 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?
오류가 발생할 가능성이 있는 함수(메서드)를 호출할 때는 try, try?, try! 를 사용하여 오류를 처리합니다.
오류를 던질 수도 있지만, 오류가 던져지는 것에 대비하여 던져진 오류를 처리하기 위한 코드도 작성해야 합니다. 예를 들어, 던져진 오류가 무엇인지 판단하여 다시 문제를 해결하거나, 다른 방법으로 시도해 보거나, 사용자에게 오류를 알리고 선택 권한을 넘겨주는 등의 코드를 작성해야 합니다.
오류 발생의 여지가 있는 'throws' 함수(메서드)는 'try' 를 사용하여 호출해야 합니다.
do {
// 돈 받기 메서드 호출, 0원을 입력하여 오류를 발생시킵니다.
try machine.receiveMoney(0)
} catch VendingMachineError.invalidInput {
// 입력 오류를 처리하는 catch 블록
print("입력이 잘못되었습니다.")
} catch VendingMachineError.insufficientFunds(let moneyNeeded) {
// 금액 부족 오류를 처리하는 catch 블록
print("\(moneyNeeded)원이 부족합니다.")
} catch VendingMachineError.outOfStock {
// 재고 부족 오류를 처리하는 catch 블록
print("수량이 부족합니다.")
} // 출력: 입력이 잘못되었습니다.
do {
// 돈 받기 메서드 호출, 정상적으로 300원을 받습니다.
try machine.receiveMoney(300)
} catch {
// 기타 모든 오류를 처리하는 catch 블록
switch error {
case VendingMachineError.invalidInput:
print("입력이 잘못되었습니다.")
case VendingMachineError.insufficientFunds(let moneyNeeded):
print("\(moneyNeeded)원이 부족합니다.")
case VendingMachineError.outOfStock:
print("수량이 부족합니다.")
default:
print("알 수 없는 오류 \(error)")
}
} // 출력: 300원 받음
do {
// 물건 팔기 메서드 호출, 4개를 팔려고 시도하여 오류를 발생시킵니다.
result = try machine.vend(numberOfItems: 4)
} catch {
// 발생한 오류를 출력합니다.
print(error)
} // 출력: insufficientFunds(100)
do {
result = try machine.vend(numberOfItems: 4)
}
// 물건 팔기 메서드 호출, 정상적으로 2개를 제공합니다.
result = try? machine.vend(numberOfItems: 2)
print(result) // Optional("2개 제공함")
// 물건 팔기 메서드 호출, 재고 부족으로 인해 nil을 반환합니다.
result = try? machine.vend(numberOfItems: 2)
print(result) // nil
// 물건 팔기 메서드 호출, 정상적으로 1개를 제공합니다.
result = try! machine.vend(numberOfItems: 1)
print(result) // 1개 제공함