스위프트5에서 새롭게 추가된 Result Type은 에러 처리할 때 사용한다.
에러가 발생하는 경우 리턴 타입 자체를 Result Type으로 구현해서
함수 실행의 성공과 실패의 정보를 담아서 반환한다.
▶️ 기존의 에러 처리인 경우, 성공과 실패에 대한 결과를 따로 처리하고
do catch 블럭으로 감싸야 한다.
에러정의
enum MyError: ErrorType {
case someError
case criticalError
}
throws를 활용한 에러처리
func doSomething() throws {
throw MyError.someError
}
do {
try doSomething()
} catch let myError as MyError {
switch myError {
case .someError:
print("someError")
case .criticalError:
print("criticalError")
}
} catch {
print(error.localizedDescription)
}
위의 방식으로 한계가 있다.
- throws 코드 블록에서 에러를 던질 수 있다는 걸 나타내지만 에러의 형식은 특정할 수 없음
- catch로 올 때 실제 에러가 아닌 에러 프로토콜 형식으로 전달되는데, 이 때 모호함이 발생함
- 에러를 처리하기 위해서는 어떤 형식의 에러를 던지는지 파악한 후 해당 형식으로 타입캐스팅을 해야함
- 새로운 에러 형식이 추가되어도 컴파일러는 인지할 수 없음 (새로운 에러에 대한 처리가 없으면 경우에 따라 런타임 에러의 위험성이 생김)
Result Type
Result Type은 열거형과 제네릭으로 선언되어있는데, 이는 형식이 명확하다는 것을 의미한다.
Suceess에는 작업의 결과가 저장되고, Failure에는 에러가 저장된다.
enum Result<Success, Failure> where Failure: Error{
case success(Success)
case failure(Failure)
}
⭐️ 함수 실행의 결과를 성공한 경우 Success에 담고, 에러가 발생한 경우 Failure에 담아 이와 관련된 case의 연관값으로 전달한다.
에러 정의
enum NumberError: Error {
case negativeNumber
case evenNumber
}
짝수 확인 함수 구현
func isOddNumber(number: Int) -> Result<Int, NumberError> {
guard number >= 0 else {
return Result.failure(NumberError.negativeNumber)
}
guard !number.isMultiple(of: 2) else {
return .failure(.evenNumber)
}
return .success(number * 2)
}
let result = isOddNumber(number: 1)
switch result {
case .success(let data):
print(data)
case .failure(let error):
print(error.localizedDescription)
}
작업이 성공하면 Int 타입의 값이 반환되고, 실패하면 NumberError가 반환된다.
에러 형식을 직접 선언하기 때문에 형식 안전성이 보장된다.
⭐️정리하면⭐️
Result Type은 success와 failure 상황에 따른 값을 타입 자체로 저장할 수 있다.
특히, failure로 인한 Error 처리를 단순하게 할 수 있다는 점이 장점이다.
타입 캐스팅 없이 에러 처리가 가능해졌다.