ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • rethrows로 에러를 다시 던져보자 🥏
    Swift 2023. 11. 3. 09:34

    안녕하세요. 그린입니다 🍏

    이번 포스팅에서는 Swift의 rethrows에 대해 한번 학습해보겠습니다 🙋🏻

     


    rethrows?

    우선 rethrows가 뭘까요?

    throws라는것은 다들 안다고 가정해보겠습니다.

    에러가 발생할 수 있는 상황에서 에러를 catch하여 에러를 다른쪽에서 처리할 수 있도록 넘겨주는것 쉽게 말해 던져주는 의미죠?

     

    그런 관점에서 rethrows는 re + throws입니다.

    즉, 다시 던져주는것인데 또 쉽게 표현해보면 넘겨진 에러에 대해 또 다른쪽으로 넘겨주는것이라고 볼 수 있어요!

     

    흠.... 말로는 사실 복잡해보이고 이해가 안갈 수 있습니다.

     

     

     

    일단 우리가 좋아하는? 코드로 쉽게 확인하기 전에 rethrows를 딱 구두로 풀어서 정의해보고 가시죠 😄

     

    공식문서에서는 rethrows가 함수나 메서드의 매개 변수 중 하나가 에러를 발생시키는 경우에만 에러를 재발생시킨다는것을 나타내는 의미로 rethrows를 사용하여 함수나 메서드를 선언할 수 있습니다.

    즉 이러한 함수와 메서드를 rethrowing function이나 rethrowing method라고 불리죠.

     

    rethrowing function이나 rethrowing method은 꼭 하나 이상의 throws 매개 변수가 존재해야 합니다.

    즉, 함수나 메서드는 클로저의 에러를 자신이 호출될때까지 연기시키고 있다가 호출되는 시점에서 호출자에게 에러를 던질 수 있게 해줍니다.

    기본적으로는, 함수나 메서드는 자신이 직접 에러를 던지지 않는 한 throws를 사용할 수 없습니다.

    그러나, rethrows는 함수, 메서드가 자신의 인자로 받은 클로저에서 에러를 던질 수 있게하기에 이런 상황에서 아주 유용하죠!

     

    그럼 진짜 본격적으로 코드로 한번 예시를 보시죠ㅎㅎ

     

    1. throws 메서드
    func alwaysThrows() throws {
      throw SomeError.error
    }
    
    2. rethrows 메서드
    func someFunction(callback: () throws -> Void) rethrows {
      try callback()
    }
    
    3. someFunction 호출
    do {
      try someFunction(callback: alwaysThrows)
    } catch {
      // 에러 처리
    }

     

    기본적으로 이렇게 사용될 수 있습니다.

    에러를 던지는 alwaysThrows 메서드가 있죠?

    그리고 throws 메서드를 매개 변수로 받는 someFunction 메서드가 있습니다.

     

    이때 someFunction 메서드를 호출하는곳에서 인자로 alwaysThrows 메서드를 넣어줍니다.

    그럼 실제로 alwaysThrows에서 에러가 발생할것이고 이는 someFunction에서 처리하지 않고 rethrows되어서 호출한곳의 catch에서 처리하게 되는 로직입니다.

     

    이렇게 rethrows를 사용할 수 있죠!

     

    또한 이렇게도 사용할 수 있습니다 🙋🏻

     

    func someFunction(callback: () throws -> Void) rethrows {
      do { 
        try callback()
      } catch {
        throws AnotherError.error
      }
    }

     

    이렇게 someFunction에서 catch하여 다른 에러를 다시 던질 수도 있죠!

     

    이렇게 자유롭게 사용할 수 있지만 주의할 사용법도 있습니다.

     

    요렇게는 사용할 수 없어요 🥲

     

    func someFunction(callback: () throws -> Void) rethrows {
      do {
        🚫 try alwaysThrows() 🚫
      } catch {
        throw AnotherError.error
      }
    }

     

    alwaysThrows란 throws 메서드를 직접 호출해서는 던질 수 없습니다. (rethrows 불가)

    왜냐하면 rethorws 메서드나 함수는 매개 변수로 들어온 인자로만 사용이 가능하다는점이에요!

     

    그리고 마지막으로 공식문서에서 몇가지 유의 사항을 말하고 있습니다.

     

    1️⃣ throws 메서드는 rethrows 메서드를 재정의 할 수 없고 throws 메서드는 rethrows 메서드에 대한 프로토콜 요구 사항을 충족할 수 없음

    2️⃣ 반면 rethrows 메서드는 throws 메서드를 재정의할 수 있고 rethrows 메서드는 throws 메서드에 대한 프로토콜 요구 사항을 충족할 수 있음

     

    클래스와 프로토콜에서의 throws와 rethrows 재정의 하는것에 대해 말하고 있습니다.

     

    즉 정리하여 한번 말해볼까요?

     

    1️⃣ 상위 클래스의 rethrows 메서드는 하위 클래스의 throws 메서드로 재정의가 되지 않으며, 반대로 상위 클래스의 throws 메서드는 하위 클래스의 rethrows 메서드로 재정의가 가능합니다.

    2️⃣ 프로토콜에서도 rethrows 메서드는 throws로 실제 구현될 수 없지만 throws 메서드 요구사항은 rethrows 메서드로 실제 구현할 수 있습니다.

     


    마무리

    자 요렇게 이번에는 한번 rethrows라는 개념에 대해 알아봤습니다!

    사실 어려운 개념이 아닌데 잘 사용해보지 않은 개념이라 생소했을뿐입니다ㅎㅎ

    활용성이 여러모로 좋을것 같습니다 😄

     


    레퍼런스

    https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations/#Rethrowing-Functions-and-Methods

     

    Documentation

     

    docs.swift.org

    'Swift' 카테고리의 다른 글

    Assertions & Preconditions  (115) 2024.01.25
    추상화와 다형성  (54) 2023.12.11
    String의 Small String Optimization  (36) 2023.10.30
    Default Initializers의 흔한 오해  (39) 2023.10.17
    Debouncer 만들기 (No Combine, No RxSwift)  (48) 2023.10.09
Designed by Tistory.