TIL(Today I Learned)

why Result Type?

기존 에러 처리
  1. 에러 정의
    • 어떤 경우의 에러가 발생할지 미리 정의
    • 개발자는 열거형 타입으로 에러를 정의해야 하며, 에러 프로토콜(Error)을 채택
enum NameError: Error{  // 개발자가 만든 열거형 타입의 에러에 에러 프로토콜(Error)을 채택
    case noName
}
  1. 에러 발생 함수 정의
    • 에러가 발생할 수 있는 함수를 정의할 때는 파라미터(parameter) 괄호 다음에 throws라는 키워드를 작성
    • throws라는 키워드를 통해 해당 함수는 “에러를 던질 수 있는 함수 타입”으로 변환
      func checkingName(name: String) throws -> String{   //throws라는 키워드를 작성
       if name.isEmpty{
        throw NameError.noName
       }
       else{
        return name
       }
      }
      
  2. 에러 발생 함수 실행
    • throws라는 키워드가 들어간 함수는 바로 사용할 수 X
    • 에러 발생 함수를 실행하기 위해서는 “do{ try }, catch{ }” 문법을 사용
      do{     // 함수를 실행하는 블럭
       try print(checkingName(name: "김철수"))
      }
      catch{  // 에러를 처리(실행)하는 블록
       print("이름이 없습니다.")
      }
      
에러처리의 단점
  1. 에러를 처리하기 위해 많은 키워드(throws, throw, do{ }, try, catch{ })를 사용

  2. 키워드를 많이 사용하다 보니 코드가 복잡해짐 -> 가독성 하락

  3. 실재 함수를 호출하는 곳에서 어떤 에러 형식 던지는지 특정짓기 어려움

Result Type

  • Result Type은 열거형(enum)으로 이루어져 있으면, 기본적인 연관값(Associated Value)을 가지고 있는 제네릭(Generics) 열거형
  • Success에는 모든 타입 가능
  • Failure에는 Error 프로토콜을 채택한 타입만 가능

Reulst Type을 사용한 에러 처리

  1. 에러정의
    • 어떤 경우의 에러가 발생할지 미리 정의
    • 개발자는 열거형 타입으로 에러를 정의해야 하며, 에러 프로토콜(Error)을 채택
      enum NameError: Error{  // 개발자가 만든 열거형 타입의 에러에 에러 프로토콜(Error)을 채택
       case noName
      }
      
  2. 에러 발생 함수 정의
    • 에러가 발생할 수 있는 함수를 정의할 때는 반환 타입을 “Result<반환 타입, Error 프로토콜을 채택한 에러 타입>”로 구현
    • 에러를 던질 때는 throw가 아닌 return을 사용하여 반환
      func checkingName(name: String) -> Result<String, NameError>{
       if name.isEmpty{
        return Result.failure(NameError.noName)
       }
       else{
        return Result.success(name)
       }
      }
      
  3. 에러 발생 함수 실행
    • 에러 발생 함수를 변수(상수)에 할당하여 switch 문과 함께 사용하면 활용성을 높일 수 있습니다. (에러 발생 함수의 타입은 Result<Success, Failure>이지만, 근본적으로 Result 타입 자체가 열거형으로 만들어지기 때문에 switch 문과 함께 사용하면 다양한 표현이 가능) ```swift let A = checkingName(name: “김철수”) let B = checkingName(name: “”)

switch A{ case .success(let data): print(data) case .failure(let error): print(error.rawValue) } // 김철수

switch B{ case .success(let data): print(data) case .failure(let error): print(error.rawValue) } // 에러: 이름이 없습니다. ```

에러 처리 VS Result Type

  • Result Type을 활용한 에러 처리는 코드의 간결화, 가독성 향상 등의 장점을 가지고 있지만 기존 에러 처리(Error Handling)를 완전하게 대체하는 것은 불가
  • 상황에 맞는 에러 처리 방식을 선택하여 코드를 작성하는 것이 중요

댓글남기기