Swift 오류처리(2020.11.3)

오류표현

Error 프로토콜과 (주로)열거형을 통해서 오류를 표현합니다

enum 오류종류이름: Error{
	case 종류1
    case 종류2
    case 종류3
    // ...
}

자판기 동작 오류의 종류를 표현한 vendingMachineError 열거형

enum VendingMachineError: Error {
	case invalidInput
    case insufficientFunds(moneyNeeded: Int)
    case outOfStock
}

함수에서 발생한 오류 던지기

자판기 동작 도중 발생한 오류 던지기
오류 발생의 여지가 있는 메서드는 throuws를 사용하여
오류를 내포하는 함수임을 표시합니다.

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 ven(numberOfItems numberOfItemsToVend: Int) throws -> String{
    	guard numberOfItemsToVend > 0 else {
        	throw VendingMachineError.invalidInput
            // 반환 타입이 String 인데 오류가 있을때는 오류를 던지고 끝!!
        }
        guard numberOfItemsToVend * itemPrice <= deposited else {
        	let moneyNeeded : Int
            moneyNeeded = numberOfItemsToVend * itemPrice - deposited
            
            throw VendingMachineError.insufficientFunds(moneyNeeded:money)
        } 
        
        // 구매하려는 수량보다 요구하는 수량이 많으면 오류를 던집니다.
        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("\(moneyNeeded)원이 부족합니다.")
} catch VendingMachineError.outOfStock {
	print("수량이 부족합니다")
} // 입력이 잘못되었습니다.
do {
	try machine.receiveMoney(300)
} catch /*(let error)*/ { // error은 추가해도 되고, 안하면 기본값으로 error이 전달된다.

	switch error {
    	case VendingMachineError.invalidInput:
        	print("입력이 잘못되었습니다.")
        case VendingMachineError.insufficientFunds(let moneyNeeded):
        	print("\(moneyNeeded)원이 부족합니다")
        case VendingMachineError.outOfStock:
        	print("수량이 부족합니다")
        default:
        	print("알수없는 오류 \(error)")
    }
}// 300원 받음


do{
	result = try machine.vend(numberOfItems:4)
} catch {
	print(error)
} // insufficientFunds(100)
// 하나하나 핸들링 할 필요가 없다면 이와 같이 작성할수 있다.



do{
	result = try machine.vend(numberOfItems:4)
}
// 에러가 발생해도 신경쓰지 않을 경우는 이와 같이 작성할수 있다.

try? 와 try!

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)

출처 : 유튜브 "yagom"

좋은 웹페이지 즐겨찾기