본문 바로가기
iOS/iOS

Result타입

by 황민우 2022. 6. 13.

정의

- Result 타입은 Generic Enumeration으로 선언되어 있고,

경우에 따른 연관 값을 포함하여, 성공과 실패를 나타내는 값입니다.

 

선언

@frozen enum Result<Success, Failure> where Failure : Error

 


 

문제점

- Error Handler을 사용했을 때, Error와 Data를 인스턴스로 다루고 있지만, 런 타임에 error와 data의 값이 모두 nil일 수 있습니다.

- 또 다른 경우로는 실제로 에러를 처리하기 위해 필요한 상태보다 더 많은 상태가 생겨 불필요한 상태를 추가로 처리해야 한다는 것입니다. 하지만 data와 error에 대한 에러 처리를 할 경우엔 총 4가지의 경우만 발생할 수 있습니다.

  1. Data = True , Error = False
  2. Data = True , Error = True 
  3. Data = False, Error = False
  4. Data = False, Error = True 

 

 

사용법

- 다음은 Result 타입의 정의입니다.

enum Result<Success, Failure: Error> {
    case success(Success)
    case failure(Failure)
}

 

- 앞의 예제를 Result 타입을 이용해 바꿔보겠습니다.

- Result를 사용하므로 모호한 상태의 처리가 없이 명시적이고 간결하게 에러 처리를 할 수 있습니다.

func load(then handler: @escaping (Result<Data>) -> Void) {
    //...
}

load { result in
    switch result {
    case .success(let data):
        // load된 data 처리
    case .failure(let error):
        // error 처리
    }
}

 

 

Result의 다양한 사용법

1, 타입에러

- 에러를 더 안전하고 정확하게 처리하기 위해 연관된 에러를 정의해 사용할 수 있습니다.

- 앞의 예제 코드에서 새로운 error 케이스를 정의하겠습니다.

enum LoadingError: Error {
    case networkUnavailable
    case timedOut
    case invalidStatusCode(Int)
}

- 에러 발생 시 LoadingError를 발생시키기위해 Result의 Error에 LoadingError 타입을 선언합니다.

typealias Handler = (Result<Data, LoadingError>) -> Void

- 생성한 Handler를 이용해 load함수를 선언합니다.

func load(then handler: @escaping Handler) {
        //...
}

- load 함수의 성공, 실패 처리를 다음과 같이 할 수 있습니다.

- 에러 발생시 직접 정의한 에러의 종류에 따라 처리할 수 있습니다.

load { [weak self] result in
    switch result {
    case .success(let data):
        self?.handle(data)
    case .failure(let error):
        switch error {
        case .networkUnavailable:
            self?.showErrorView(withMessage: .unavailable)
        case .timedOut:
            self?.showErrorView(withMessage: .timedOut)
        case .invalidStatusCode(let code):
            self?.showErrorView(withMessage: .statusCode(code))
        }
    }
}

 

 

2, Throw 처리

- 작업 결과의 처리를 try, do, catch에서 직접 할 경우, 다음과 같이 할 수 있습니다.

- 성공 시 결괏값을 반환하고, 실패 시 throw 처리를 통해 해당 블록에서 탈출시킬 수 있습니다.

extension Result {
    func process() throws -> Success {
        switch self {
        case .success(let value)
            return value
        case .failure(let error)
            throw error
        }
    }
}
do {
    let result = try value?.process()
    handleValue(result)
}
catch {
    handleError(error)
}

 

 

 

3, 지연처리

- 에러 처리를 바로 하지 않고 나중에 하고 싶을 때 사용할 수 있습니다.

Result 타입을 사용하지 않았을 때 코드

var configString: String?
var configError: Error?

do {
    configString = try String(contentsOfFile: "myfile.data")
} catch {
    configError = error
}

func doSomethingWithConfig() {
    guard let configString = self.configString else {
        handle(configError)
    }
}

Result 타입을 사용할 때 코드

let configuration = Result { try String(contentsOfFile: "myfile.data") }

func doSomethingWithCongifg() {
    switch configuration {
    case .success(let success)
        handleSuccess(success)
    case .failure(let error)
        handlError(error)
    }
}

 

 

 

4, Result 변형

- Result는 고차 함수를 지원합니다.

func generateRandomNumber(maximum: Int) -> Result<Int, Error> {
    //...
}

let result = generateRandomNumber(maximum: 7)
let number = result.map { "Generated Random number is : \($0)" }

 


내용 출처

https://jusung.github.io/Result-%ED%83%80%EC%9E%85/

 

[Swift] Result 타입

개 요 작업(Task) 중에는 실패할 수 있는 작업이 있습니다. 디스크에 파일을 쓰거나, API를 호출해 네트워크를 통해 데이터를 가져온다거나, 특정 URL에 있는 데이터를 불러오는 작업이 이 경우에

jusung.github.io

https://hryang.tistory.com/21

 

Swift 의 Result 타입에 대해서 알아봅시다

굿데이 여러분 오늘은 Swift 에서 제공해주는 Result 에 대해서 간단히 알아보는 시간을 가져보도록 하겠습니다 일단 정의를 보면 이렇게 나와있네여 A value that represents either a success or a failure, inc..

hryang.tistory.com

https://velog.io/@un1945/Swift-Result-Type

 

[Swift] Result Type

안녕하세요! Kio입니다 👻 지난 번 에러처리(Error Handling) 를 다룬 적이 있었는데요. 오늘은 그 이후에 도입된 Result Type 에 대해 알아보고자 합니다. Let's get started 🥰 Why Result Type? > 그렇다면 왜 R

velog.io

 

'iOS > iOS' 카테고리의 다른 글

Equatable  (0) 2022.06.17
Hashable  (0) 2022.06.16
접근 제어자의 종류  (0) 2022.06.11
NSCache와 NSDictionary의 차이를 설명하시오.  (0) 2022.06.09
NSCache  (0) 2022.06.08

댓글