본문 바로가기

# 02/Swift

[Swift] 오류처리

반응형

오류표현


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