함수나 메서드는 rethrows키워드를 사용하여 자신의 매개변수로 전달받은 함수가 오류를 던진다는 것을 나타낼 수 있습니다.
최소 하나 이상의 오류 발생 가능한 함수를 매개변수로 전달받아야합니다.
간단한 예제를 보면서 살펴보겠습니다.
enum MyError: Error {
case cannotDivide
}
func divideNumber(first: Float, second: Float) throws -> Float {
if second == 0 {
throw MyError.cannotDivide
}
return first/second
}
func calculateFunction(function: (Float, Float) -> Float) {
print(function(2, 3))
}
calculateFunction(function: divideNumber) // Compile Error
non-throwing함수를 파라미터로 받는 함수인 calculateFunction에 throwing함수인 divideNumber를 넘겨주는 부분에서 에러가 발생합니다.
rethorws를 사용하지 않고 위 코드를 해결하기 위한 일반적인 코드는 아래와 같을 것입니다.
func calculateFunction(function: (Float, Float) throws -> Float) {
do {
print(try function(2, 0))
} catch let error as MyError {
// Error Handling..
}
}
파라미터 중에 함수 하나가 에러를 throws하는 경우에 에러를 던질 수 있도록 암시하도록 함수를 선언할 때, rethrows 키워드를 넣어야합니다.
enum MyError: Error {
case cannotDivide
}
func divideNumber(first: Float, second: Float) throws -> Float {
if second == 0 {
throw MyError.cannotDivide
}
return first/second
}
func calculateFunction(function: (Float, Float) throws -> Float) rethrows {
print(try function(2, 0))
}
do {
try calculateFunction(function: divideNumber)
} catch let error as MyError {
switch error {
case .cannotDivide:
print("0으로 나누었다.")
}
}
calculateFunction 함수가 파라미터로 throwing함수를 받도록 명시하고, 해당 함수에서 받은 에러를 다시 던질 수 있도록 명시해주는 것입니다.
그 외
부모클래스에서의 rethrows는 자식클래스에서 throws로 재정의가 불가능합니다. 그러나 부모클래스의 throws는 자식클래스에서 rethrows로 재정의가 가능합니다.
프로토콜 요구사항 중에 rethrows가 있다면, throws를 구현한다고 해서 요구사항을 충족시킬 수 없습니다.
반대로 throws가 있다면 rethrows를 구현해서 요구사항을 충족시킬 수 있습니다.
마무리
사용하면서 throws와 비슷해보이지만 rethrows는 파라미터로 전달받은 함수가 에러를 던질 때 사용하면 될 것 같습니다.
*reference
- 스위프트 프로그래밍 3판 - 야곰
'Swift' 카테고리의 다른 글
[Swift] 에러처리 전략 (2) | 2020.02.23 |
---|---|
[Swift] Extension이란 (0) | 2020.01.05 |
[Swift] SwiftLint 적용하기 (0) | 2020.01.05 |
[Swift] Extension(확장)으로 코드 가독성 올리기 (0) | 2020.01.05 |
[Swift] 구조체란 무엇인가? (0) | 2020.01.03 |