Swift에서 throw와 rethrows의 차이점은 무엇입니까?
일부 참고 문헌을 검색 하시나요을 파악 후, 나는 사이의 차이를 이해에 대한 유용한 - 그리고 SIMPLE- 설명을 찾을 수 없습니다 -unfortunately- throws
와 rethrows
. 우리가 그것들을 어떻게 사용해야하는지 이해하려고 할 때 다소 혼란 스럽습니다.
나는 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)
그러나 map
throwing 클로저로 호출 되면 자체적으로 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 asthrows
instead ofrethrows
then you would have to call it withtry
even in example 1, which is "inconvenient" and bloats the code unnecessary. - If
map
were declared withoutthrows/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.
'Nice programing' 카테고리의 다른 글
ActiveRecord where field =? (0) | 2020.11.26 |
---|---|
Spring Boot 애플리케이션의 환경 별 application.properties 파일 (0) | 2020.11.26 |
내 web.config 파일에 사전 객체를 저장하려면 어떻게합니까? (0) | 2020.11.26 |
Android에서 GUID를 얻는 방법은 무엇입니까? (0) | 2020.11.26 |
MSTest : 테스트가로드되지 않았거나 선택한 테스트가 비활성화 되었기 때문에 테스트가 실행되지 않습니다. (0) | 2020.11.26 |