일부 참고 문헌을 검색 하시나요을 파악 후, 나는 사이의 차이를 이해에 대한 유용한 – 그리고 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 {
// ...
}
- 대신에
map
선언 된 경우 예제 1에서도 호출해야합니다 . 이는 “불편하고”코드를 불필요하게 부풀립니다.throws
rethrows
try
- 그
map
없이 선언 된 경우throws/rethrows
예제 2에서와 같이 throwing 클로저로 호출 할 수 없습니다.
함수 매개 변수 filter()
인 index(where:)
, forEach()
등 을 사용하는 Swift Standard Library의 다른 메서드도 마찬가지입니다 .
귀하의 경우에는
func throwCustomError(function:(String) throws -> ()) throws
던지지 않는 인수로 호출 되더라도 오류가 발생할 수있는 함수를 나타냅니다.
func rethrowCustomError(function:(String) throws -> ()) rethrows
throwing 인수로 호출되는 경우에만 오류를 발생시키는 함수를 나타냅니다.
대략적으로 말하자면, rethrows
“자체적으로”오류를 발생시키지 않고 함수 매개 변수에서 “전달”오류 만 발생시키는 함수를위한 것입니다.
답변
Martin의 대답과 함께 무언가를 추가하십시오. 던지는 함수와 동일한 시그니처를 가진 던지지 않는 함수는 던지는 함수로 간주 sub-type
됩니다. 그렇기 때문에 rethrows는 그것이 무엇인지 결정할 수 try
있고 func param도 throw 할 때만 필요 하지만 throw되지 않는 동일한 함수 서명을 여전히 받아들입니다. func 매개 변수가 발생할 때 do try 블록 만 사용하면되는 편리한 방법이지만 함수의 다른 코드는 오류를 발생시키지 않습니다.