-
Swift - Error Handling (throws와 rethrows)Programming/Swift 2022. 3. 27. 12:36
안녕하세요 BeePeach입니다 :)
오늘은 이전에 공부했던 throws와 헷갈리기 쉬운 rethrows에 대해서 공부해보도록 하겠습니다.
throws
throws 키워드 말고 rethrows라는 키워드도 존재합니다.
rethrows는 파라미터로 throws를 포함하는 함수를 받을 때 사용하는 키워드입니다.
중요한 것은 '파라미터로 throws 함수를 받는다'라는 것입니다.
그냥 외부에 존재하는 throws 함수를 사용하는 것과 구별해야 합니다.
MyError를 정의해주고 someErrorFunction을 정의했습니다.
이 함수는 단순하게 Error를 던지는 함수입니다.
내부에서 Error를 throw 하고 있으니까 throws 키워드를 사용해줘야겠죠?
여기까지는 이전 포스팅에서 공부한 내용입니다.
그리고 파라미터로 callback이라는 이름으로 throws 함수를 받는 함수 2개를 선언했습니다.
nonThrowsFunction(callback:) 함수는 throws 키워드가 없습니다.
throwsFunction(callback:) 함수는 throws 키워드가 있습니다.
그리고 두 함수 모두 파라미터로 callback이라는 함수를 받습니다.
그런데 이 파라미터 함수는 throws 키워드를 가지고 있습니다.
그럼 파라미터 함수를 호출할 때 try를 적어서 이 파라미터가 호출할 때 Error가 발생할 수 있는 함수라고 알려줘야 하죠?
이때 함수에 throws 키워드가 있다면 그냥 try만 적어주고 파라미터를 호출해도 문제가 없습니다.
이전 포스팅에서 배운 Propagate Error를 이용한 에러 처리 방법이죠.
하지만 throws 키워드가 없는 nonThrowsFunction(callback:) 함수는 그냥 try만을 사용하면 안됩니다.
do-catch를 이용하거나 try? try!를 이용해서 에러 처리를 해줘야 합니다.
여기까지도 이전 포스팅에서 배운 내용입니다.
그럼 이제 진짜 rethrows를 다뤄보도록 하겠습니다.
rethrows
throws와 비교하기 위해서 이전에 정의했던 throwsFunction(callback:)과 함께 보도록 하겠습니다.
rethrows는 throws 대신 rethrows를 적어주면 됩니다.
여기서 중요한 점은 파라미터로 전달되는 함수가 throws일 때 적어주는 것입니다.
그냥 파라미터로 기본 함수가 전달되는데 rethrows를 적으면 컴파일 에러가 발생합니다.
그럼 여기서 간단한 차이점을 살펴보도록 하겠습니다.
먼저 rethrows 함수는 내부에서 바로 throw 키워드를 사용할 수 없습니다.
rethrowsFunction(callback:) 함수를 보면 바로 throw를 사용했는데 에러가 나는 것을 확인할 수 있습니다.
반면에 throwsFunction(callback:) 함수는 throw를 바로 사용해도 에러가 나지 않습니다.
이 부분은 throw를 사용하고 싶다면 함수에 throws 키워드를 적어줘야 했다는 것을 기억해주시면 됩니다.
그럼 그렇다고 rethrows에서 throw키워드를 완전히 못쓰는 것일까요?
그건 아닙니다.
do-catch에서 catch 부분에서 throw를 사용할 수 있습니다.
그런데 여기서도 주의할 점은 파라미터로 전달된 함수가 아니라면 throw 할 수 없습니다.
anotherRethrowsFunction(callback:) 함수를 보면 파라미터로 받은 함수에 대해서는 throw 할 수 있지만 외부에 존재하는 함수는 throw할 수 없는 것을 확인할 수 있습니다.
그 이유는 rethrows가 파라미터로 받은 함수에 대해서 작용하는 키워드이기 때문입니다.
그런데 이 부분만 차이가 있다면 의아한 부분이 많습니다.
아니 그냥 다 throws로 하면 내부에서 바로 throw도 할 수 있고 외부 함수에 대해서 throw로 할 수 있는데 뭐하러 rethrows를 써?
위 예시에도 throwsFunction(callback:) rethrowsFucntion(callback:)은 throws와 rethrows 키워드를 제외하면 겉보기에 차이가 없습니다.
그리고 반드시 파라미터로 throws함수를 받으면 rethrows를 사용해야 해!라는 제약이 걸린 것도 아닙니다.
예시에서도 보면 파라미터로 throws 함수를 받을 때 rethrows대신 throws키워드를 사용해도 무리가 없습니다.
오히려 rethrows를 사용하면 제약이 더 생기는 것같이 보입니다.
사용성의 차이
rethrows를 사용하고 있는 예시를 보면 왜 rethrows를 사용하는지 이해할 수 있습니다.
흔히 접할 수 있는 예시로는 map, filter, reduce가 있습니다.
rethrows로 되어있는 것을 확인할 수 있죠?
그럼 갑자기 드는 생각이 있습니다.
어?? 우리가 이 고차 함수들을 사용할 때 try를 사용했던가...?
맞습니다!
우리는 이런 고차 함수를 쓸 때 대부분의 경우 try를 붙여주지 않았습니다.
그냥 사용했죠. 그래서 사실 이 함수가 rethrows인지도 모르고 있을 확률이 높습니다.
rethrows의 핵심은 파라미터로 전달되는 함수가 throws 함수이지만 사용할 때 파라미터로 전달된 함수가 throws함수가 아닐 수 있다는 점에 있습니다.
throws 함수를 파라미터로 받으니까 받는 함수가 반드시 throws일거라고 생각하면 안 됩니다. 그냥 일반 함수가 전달돼도 괜찮습니다.
우리가 map, filter를 사용할 때 throws 클로저를 사용한 게 아니였잖아요?
예시를 보겠습니다.
throws 함수는 호출할 때 파라미터로 전달되는 함수가 throws이던 아니던 무조건 try를 적어줘야 합니다.
그런데 rethrows 함수는 호출할 때 파라미터로 전달되는 함수가 throws가 아니라면 try를 적어주지 않아도 됩니다.
rethrows함수는 throw함수와 달리 직접 에러를 throw 하는 게 아니기 때문입니다.
예시에서도 rethrowsFunction(callback:)을 호출하는데 파라미터로 그냥 함수를 전달할 때 try를 사용하지 않는 것을 확인할 수 있습니다.
정리
이렇게 rethrows와 throws의 차이를 공부해보았습니다.
정리하자면
- 파라미터로 throws함수를 받으면 rethrows, throws 키워드를 사용할 수 있다.
- rethrows를 사용하면 throw 키워드를 바로 사용할 수 없다.
- rethrows에서 throw 키워드를 사용하고 싶다면 파라미터로 받은 함수를 do-catch로 처리할 때 사용할 수 있다.
- throws는 사용 시에 반드시 try를 사용해야 하지만 rethrows는 파라미터로 받은 함수가 throws가 아니라면 try를 사용하지 않아도 된다.
참고 자료
https://book.naver.com/bookdb/book_detail.nhn?bid=15479573
https://docs.swift.org/swift-book/ReferenceManual/Declarations.html
728x90'Programming > Swift' 카테고리의 다른 글
Swift - Result Type (0) 2022.03.30 Swift - Error Handling(do-catch, try?, try!) (0) 2022.03.29 Swift - Error Handling(throws) (0) 2022.03.25 Swift - Error Handling 기초 (0) 2022.03.24 Swift - UserDefaults에 customType 저장하기 (0) 2022.03.01