참고사이트
Result의 탄생배경 : https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md
(Github의 README를 참고할 수도 있구나)
Result
는 try catch와 마찬가지로 에러 핸들링을 위한 문법입니다
try catch는 '에러 자동 전파 시스템'이라 볼 수 있지만, Result는 보통 반환값으로 사용되어 밖에서 이를 직접 처리하게 하는 '수동 전파' 방식입니다
'Data 또는 Error를 던져줘야 하는 경우'에 좋은 대안입니다
try
/catch
는 Swift의 '에러 자동 전파 시스템'이라 합니다.
하지만, 모든 에러를 전파하고 처리함에 있어 flexibility가 부족합니다
-> 비동기 작업, 복잡한 에러 처리, Error 프로토콜을 준수하지 않는 에러값을 다루기 어렵다
타입화(typed)되고 표시(marked)되지만 에러타입을 '수동전파'함으로써 증가되는 flexibility가 이런 문제를 해결해줍니다. (직역 죄송;;)
try catch
를 쓸 수 없는 이유결론 :
throw
를 처리할(catch
) 자리가 없다
비동기 작업(async
)은 작업의 결과를 호출한 곳으로 반환하는 것이 아니라 '완료 클로저'를 수행함으로써 이루어진다는 특징이 있습니다
이 때문에,
비동기 작업을 시작하는 함수는 : 비동기 작업의 '등록'과정을 거치고 단순 return 되어 버리고,
완료 클로저에서는 : catch
문을 찾으러 올라갈 호출 함수가 존재하지 않아
-> throw
를 넣을 자리가 없다
따라서 비동기 작업에선, 호출 함수를 타고 올라가며 catch를 찾는 '에러 자동 전파 시스템'을 사용할 수 없고
'완료 클로저'가 에러 정보를 반환하도록 설정하여 완료 클로저들을 처리하는 곳에서 switch 등의 조건문으로 에러 여부를 구분하여 처리해야 한다
완료 클로저는 Data를 반환해야 하는 경우도 많으므로 결국 Error(종류) 혹은 Data를 반환해야 하는 경우라 볼 수 있으며 Result
가 대안이 될 수 있다
사실 너무 간단해서..
enum myError: Error {
case tooLowData
}
func myFunction(data: Int) -> Result<Int,myError> {
if data > 3 {
return .success(data)
} else {
return .failure(.tooLowData)
}
}