[Swift 기초] 오류처리
2022. 4. 11. 16:15ㆍSwift 기초 정리
728x90
//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎
1. 오류 표현
enum 오류종류이름: Error {
case 종류1
case 종류2
case 종류3
//...
}
- Error 프로토콜과 주로 열거형을 통해 오류를 표현한다.
- Error 프로토콜
- 내부적으로는 비어있는 프로토콜
- Error를 구현한다는 의미가 중요한 프로토콜
- Error 프로토콜을 열거형에 추가한 후 열거형 내에 오류들을 정의
1-1. 예시
//오류를 표현하기 위한 열거형
//자판기 동작 오류
enum VendingMachineError: Error {
case invalidInput
case insufficientFunds(moneyNeeded: Int)
case outOfStock
}
1-2. 함수에서 발생한 오류 던지기
- 특정한 함수 안에서 오류가 발생한 곳에(= 자신을 호출한 곳에) 오류를 던저준다 : throws 키워드 사용
- 오류가 발생의 여지가 있는 메서드는 throws를 사용하여 오류를 내포하는 함수임을 표시
- 함수 선언문의 () 뒤에, 반환타입 앞에 throws 키워드 삽입
- throws가 없으면 일반 함수
- 내부에서 오류를 던질 때는 throw 키워드 사용
class VendingMachine {
let itemPrice: Int = 100
var itemCount: Int = 5
var deposited: Int = 0
// 돈 받기 메서드
//throws: 오류가 발생할 여지가 있음
func receiveMoney(_ money: Int) throws {
// 입력한 돈이 0이하면 오류를 던집니음
//guard문을 사용하여 빠른 종료 유도
guard money > 0 else {
throw VendingMachineError.invalidInput
}
// 오류가 없으면(= guard문을 통과하게 되면) 정상처리를 합니다
self.deposited += money
print("\\(money)원 받음")
}
// 물건 팔기 메서드
//throws: 오류가 발생할 수 있다를 표시, 리턴 타입을 뒤에 표기
func vend(numberOfItems numberOfItemsToVend: Int) throws -> String {
//여러가지 오류사항이 발생할 수 있다.
// 원하는 아이템의 수량이 잘못 입력되었으면 오류를 던집니다
guard numberOfItemsToVend > 0 else {
//String을 리턴하지 않고 throws로 함수를 끝내버림: 함수를 끝내면서 오류를 던져버림
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 -= numberOfItemsToVen
return "\\(numberOfItemsToVend)개 제공함"
}
}
// 자판기 인스턴스
let machine: VendingMachine = VendingMachine()
// 판매 결과를 전달받을 변수
var result: String?
- guard문을 통해서 빠른 종료를 유도할 수 있다. guard문을 통과해서 오류가 없다면 정상 동작 처리
- 하나의 메서드에 여러 오류가 발생할 여지가 있다 → guard문으로 각각 오류 표현
func vend(numberOfItems numberOfItemsToVend: Int) throws -> String {
- throws 뒤에 리턴타입을 표기
- 오류가 발생하면 리턴타입을 리턴하지 않고 throws로 함수를 끝낸다: 함수를 끝내면서 throws를 던짐
2. 오류처리
- 오류를 던질 수도 있지만 오류가 던져지는 것에 대비하여 던져진 오류를 처리하기 위한 코드도 작성해야 한다.
- 던져진 오류가 무엇인지 판단해서 다시 문제를 해결한다
- 다른 방법으로 시도한다
- 사용자에게 오류를 알리고 사용자에게 선택 권한을 넘겨주어 다음에 어떤 동작을 하게 할 것인지 결정하도록 유도
- 오류 발생의 여지가 있는 throws 함수(메서드)는 try를 사용하여 호출해야 한다.
- try, try?, try!
- Java의 try-catch 구문을 사용해서 런타임시의 오류를 처리
2-1. do-catch
do{
try expression
statments
} catch pattern1 {
statments
} catch pattern2 where condition {
statements
} catch {
statements
}
- 오류발생의 여지가 있는 메서드는 try를 사용해야 하는데, 이 때 do-catch 구문을 함께 사용
- try는 오류처리 함수 호출, catch는 이를 처리
- 와일드 카드 catch문을 사용하면 이전의 catch에서 잡지 못한 error를 처리
do {
try machine.receiveMoney(0)
} catch VendingMachineError.invalidInput {
print("입력이 잘못되었습니다")
} catch VendingMachineError.insufficientFunds(let moneyNeeded) {
print("\\(moneyNeeded)원이 부족합니다")
} catch VendingMachineError.outOfStock {
print("수량이 부족합니다")
} catch {
print("와일드 카드 catch문: 이전에 잡지 못한 에러들을 처리")
// 입력이 잘못되었습니다
2-1-1. do-catch + switch
- 표현만 다를 뿐 동일하게 동작
- swich에서 사용하는 error는 catch구문에서 암시적으로 인식해서 전달
//catch를 많이 쓰기 싫다면 하나의 catch 블럭에서 swift구문으로 오류 분류
//던져진 error를 받아서 처리
//error 변수명은 catch구문으로 암시적으로 인식
do {
try machine.receiveMoney(300)
} catch /*(let error)*/ {
switch error {
case VendingMachineError.invalidInput:
print("입력이 잘못되었습니다")
case VendingMachineError.insufficientFunds(let moneyNeeded):
print("\\(moneyNeeded)원이 부족합니다")
case VendingMachineError.outOfStock:
print("수량이 부족합니다")
default:
print("알수없는 오류 \\(error)")
}
} // 300원 받음
2-1-2. catch 구문 내부 간략화
- 케이스별로 오류처리를 할 필요가 없을 때
do {
result = try machine.vend(numberOfItems: 4)
} catch {
print(error)
} // insufficientFunds(100)
2-1-3. 오류처리필요가 없을 때
- do 구문만 사용
do {
result = try machine.vend(numberOfItems: 4)
}
2-2. try
- 별도의 오류처리 결과를 통보받지 않고
- 오류가 발생했으면 결과값을 nil로 돌려 받음
- 정상동작 후에는 옵셔널 타입으로 정상 반환값을 돌려 받음
- do-catch 사용하지 않고 try?만 사용
//정상동작
result = try? machine.vend(numberOfItems: 2)
result //Optional("2개 제공함")
//오류발생
result = try? machine.vend(numberOfItems: -3)
result //nil
2-3. try!
- 오류가 발생하지 않을 것이라는 강력한 확신을 가질 때 사용
- 정상동작 후에 바로 옵셔널이 아닌 일반 타입의 결과값을 돌려 받음
- 오류가 발생하면 런타임 오류가 발생하여 애플리케이션 동작 중지
//정상동작
result = try! machine.vend(numberOfItems: 1)
result //2개 제공함
//오류발생
//VendingMachineError.invalidInput
result = try! machine.vend(numberOfItems: -1)
참고하였습니다. 감사합니다.
https://yagom.net/courses/swift-basic/lessons/오류처리/
https://www.inflearn.com/course/창원대학교-박동규-교수의-swift-기초-강좌/lecture/1905?tab=curriculum
728x90
'Swift 기초 정리' 카테고리의 다른 글
[Swift 기초] 접근제어 (0) | 2022.04.13 |
---|---|
[Swift 코테 기초] 고차함수 (0) | 2022.04.12 |
[Swift 기초] 익스텐션 (0) | 2022.04.05 |
[Swift 기초] 프로토콜 (0) | 2022.04.05 |
[Swift 기초] assert와 guard (0) | 2022.04.05 |