swift rethrows
함수나 메서드는 rethrows 키워드를 사용하여 선언할 수 있음.
이는 함수 매개변수 중 하나가 에러를 던질 경우에만 에러를 던진다는 것을 의미.
이러한 함수와 메서드를 rethrowing 함수(rethrowing functions) 또는 rethrowing 메서드(rethrowing methods)라고 부름.
func someFunction(callback: () throws -> Void) throws {
try callback()
}
rethrowing 함수와 메서드는 적어도 하나의 throwing 함수 매개변수를 가져야 함.
rethrowing 함수나 메서드는 오직 catch 블록 안에서만 throw 문을 포함할 수 있음.
이 규칙을 통해 do-catch 구문 안에서 throwing 함수를 호출하고, catch 블록에서 다른 에러를 던지며 에러를 처리할 수 있음.
또한 catch 블록은 반드시 rethrowing 함수의 throwing 매개변수 중 하나가 던진 에러만 처리해야 함.
예를 들어, 다음 코드는 잘못된 코드입
왜냐하면 catch 블록에서 alwaysThrows()가 던진 에러를 처리하려고 하기 때문
func alwaysThrows() throws {
throw SomeError.error
}
func someFunction(callback: () throws -> Void) rethrows {
do {
try callback()
try alwaysThrows() // Invalid, alwaysThrows() isn't a throwing parameter
} catch {
throw AnotherError.error
}
}
throwing 메서드는 rethrowing 메서드를 오버라이드할 수 없음.
throwing 메서드는 rethrowing 메서드에 대한 프로토콜 요구사항을 충족할 수 없음.
반대로, rethrowing 메서드는 throwing 메서드를 오버라이드할 수 있음.
rethrowing 메서드는 throwing 메서드에 대한 프로토콜 요구사항을 충족할 수 있음.
또한, rethrowing 대신 제네릭 코드에서 특정 에러 타입을 throw하는 방법을 사용할 수도 있음.
func someFunction<E: Error>(callback: () throws(E) -> Void) throws(E) {
try callback()
}
이러한 방식으로 에러를 전달하면 에러 타입에 대한 정보를 그대로 보존할 수 있음.
하지만, rethrows로 함수를 표시하는 것과 달리, 이 방식은 동일한 타입의 에러를 함수가 직접 던지는 것을 막아주지는 않음.
코드 샘플
//
// RethrowsExample.swift
// ArchitetureExample
//
// Created by Geon Woo lee on 12/2/25.
//
import Foundation
fileprivate enum SomeError: Error {
case error
}
fileprivate enum AnotherError: Error {
case error
}
fileprivate final class SomeClass {
func alwaysThrows() throws {
throw SomeError.error
}
func someFunction(callback: () throws -> Void) throws {
try callback()
}
// func someFunction(callback: () throws -> Void) rethrows {
// do {
// try callback()
// try alwaysThrows() // Invalid, alwaysThrows() isn't a throwing parameter
// } catch {
// throw AnotherError.error
// }
// }
func someFunction2(callback: () throws -> Void) rethrows {
try callback()
}
func someFunction3(callback: () throws -> Void) throws {
do {
try callback()
try alwaysThrows()
} catch {
throw AnotherError.error
}
}
func someFunction4(callback: () throws -> Void) throws {
do {
try callback()
try alwaysThrows()
} catch {
throw AnotherError.error
}
}
func someFunction5<E: Error>(callback: () throws(E) -> Void) throws(E) {
try callback()
}
}
import SwiftUI
fileprivate struct PreviewView: View {
var body: some View {
Button {
buttonTapped4()
} label: {
Text("Button")
}
}
private func buttonTapped() {
do {
let someClass = SomeClass()
try someClass.someFunction(callback: someClass.alwaysThrows)
} catch {
print(type(of: error)) // SomeError
}
}
private func buttonTapped2() {
do {
let someClass = SomeClass()
try someClass.someFunction2(callback: someClass.alwaysThrows)
} catch {
print(type(of: error))
}
}
private func buttonTapped3() {
do {
let someClass = SomeClass()
try someClass.someFunction3 { }
} catch {
print(type(of: error)) // AnotherError
}
}
private func buttonTapped4() {
do {
let someClass = SomeClass()
try someClass.someFunction4 { }
} catch {
print(type(of: error)) // AnotherError
}
}
private func buttonTapped5() {
let someClass = SomeClass()
someClass.someFunction5 { }
}
}
#Preview {
PreviewView()
}
(참고)
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations
'apple > iOS, UIKit, Documentation' 카테고리의 다른 글
| AssetInventory 정리 + AssetInstallationRequest (0) | 2025.11.22 |
|---|---|
| SpeechAnalyzer (0) | 2025.11.22 |
| SpeechTranscriber 정리 + DictationTranscriber (0) | 2025.11.22 |
| sending parameter and result values (0) | 2025.10.07 |
| Region based Isolation (0) | 2025.10.06 |