Nice programing

Swift에서 throw와 rethrows의 차이점은 무엇입니까?

nicepro 2020. 11. 26. 19:52
반응형

Swift에서 throw와 rethrows의 차이점은 무엇입니까?


일부 참고 문헌을 검색 하시나요을 파악 후, 나는 사이의 차이를 이해에 대한 유용한 - 그리고 SIMPLE- 설명을 찾을 수 없습니다 -unfortunately- throwsrethrows. 우리가 그것들을 어떻게 사용해야하는지 이해하려고 할 때 다소 혼란 스럽습니다.

나는 throws다음과 같이 오류를 전파하는 가장 간단한 형식으로 -default-에 익숙하다고 언급하고 싶습니다 .

enum CustomError: Error {
    case potato
    case tomato
}

func throwCustomError(_ string: String) throws {
    if string.lowercased().trimmingCharacters(in: .whitespaces) == "potato" {
        throw CustomError.potato
    }

    if string.lowercased().trimmingCharacters(in: .whitespaces) == "tomato" {
        throw CustomError.tomato
    }
}

do {
    try throwCustomError("potato")
} catch let error as CustomError {
    switch error {
    case .potato:
        print("potatos catched") // potatos catched
    case .tomato:
        print("tomato catched")
    }
}

지금까지는 훌륭했지만 다음과 같은 경우 문제가 발생합니다.

func throwCustomError(function:(String) throws -> ()) throws {
    try function("throws string")
}

func rethrowCustomError(function:(String) throws -> ()) rethrows {
    try function("rethrows string")
}

rethrowCustomError { string in
    print(string) // rethrows string
}

try throwCustomError { string in
    print(string) // throws string
}

하는 함수를 호출 할 때 내가 지금까지 알고있는 것은 throws그것이 의해 처리되어야한다 try달리 rethrows. 그래서 뭐?! throws또는 사용을 결정할 때 따라야 할 논리는 무엇입니까 rethrows?


에서 "선언" 스위프트의 책 :

다시 던지는 기능 및 방법

함수 또는 메소드는 rethrows함수 매개 변수 중 하나가 오류를 발생시키는 경우에만 오류가 발생 함을 나타 내기 위해 키워드로 선언 될 수 있습니다 . 이러한 기능과 방법을 다시 던지기 기능 및 다시 던지기 방법이라고 합니다. 다시 던지는 함수와 메서드에는 던지는 함수 매개 변수가 하나 이상 있어야합니다.

일반적인 예는 다음과 map같습니다.

public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

경우 map비 던지는 불려 그 자체를 오류가 발생하지 않으며없이 호출 할 수 있습니다, 변환 try:

// Example 1:

let a = [1, 2, 3]

func f1(n: Int) -> Int {
    return n * n
}

let a1 = a.map(f1)

그러나 mapthrowing 클로저로 호출 되면 자체적으로 throw 될 수 있으며 다음과 같이 호출되어야합니다 try.

// Example 2:

let a = [1, 2, 3]
enum CustomError: Error {
    case illegalArgument
}

func f2(n: Int) throws -> Int {
    guard n >= 0 else {
        throw CustomError.illegalArgument
    }
    return n*n
}


do {
    let a2 = try a.map(f2)
} catch {
    // ...
}
  • If map were declared as throws instead of rethrows then you would have to call it with try even in example 1, which is "inconvenient" and bloats the code unnecessary.
  • If map were declared without throws/rethrows then you could not call it with a throwing closure as in example 2.

The same is true for other methods from the Swift Standard Library which take function parameters: filter(), index(where:), forEach() and many many more.

In your case,

func throwCustomError(function:(String) throws -> ()) throws

denotes a function which can throw an error, even if called with a non-throwing argument, whereas

func rethrowCustomError(function:(String) throws -> ()) rethrows

denotes a function which throws an error only if called with a throwing argument.

Roughly speaking, rethrows is for functions which do not throw errors "on their own", but only "forward" errors from their function parameters.


Just to add something along with Martin's answer. A non throwing function with the same signature as a throwing function is considered a sub-type of the throwing function. That is why rethrows can determine which one it is and only require try when the func param also throws, but still accepts the same function signature that doesn't throw. It's a convenient way to only have to use a do try block when the func param throws, but the other code in the function doesn't throw an error.

참고URL : https://stackoverflow.com/questions/43305051/what-are-the-differences-between-throws-and-rethrows-in-swift

반응형