Section 2/91 menit

2. Teori: Cara Kerja Typed Throws

2. Teori: Cara Kerja Typed Throws

Unified Error Handling Model

Swift 6 menyatukan semua varian error handling dalam satu sintaks throws(E):

swift
throws(Never)  ≡  tidak throws (non-throwing)
throws         ≡  throws(any Error)  — backward compatible
throws(E)      ≡  hanya bisa lempar tipe E yang concrete

Ini bukan fitur terpisah — ini generalisasi dari sistem yang sudah ada. throws biasa sekarang secara konseptual adalah throws(any Error).

Memory Model: Menghindari Existential Boxing

Di Swift 5, semua error di-box sebagai any Error existential:

swift
Error value → heap allocation → existential container → catch block

Dengan typed throws menggunakan concrete type:

swift
Error value → langsung di stack/registercatch block

Untuk kode yang performance-critical (misalnya parsing loop yang memproses jutaan record), perbedaan ini signifikan karena menghilangkan heap allocation per-error.

Subtyping: throws adalah supertipe

Karena throws = throws(any Error), fungsi throws(MyError) adalah subtype dari throws(any Error):

swift
func specific() throws(NetworkError) -> Int { 42 }
func general() throws -> Int { 42 }

// Aman: assign more specific ke more general
let fn: () throws -> Int = specific  // OK
// Tidak aman sebaliknya:
// let fn2: () throws(NetworkError) -> Int = general  // ERROR

Never sebagai Error Type

throws(Never) adalah cara formal menyatakan "tidak pernah throws" — secara semantik sama dengan tidak menulis throws sama sekali, tapi berguna dalam konteks generic:

swift
// Generic function yang bisa throwing atau non-throwing
func transform<T, E: Error>(_ value: T, using fn: (T) throws(E) -> T) throws(E) -> T {
    try fn(value)
}

// Penggunaan non-throwing: E = Never, tidak perlu try
let result = transform(5, using: { $0 * 2 })  // tidak throws, tidak perlu try

// Penggunaan throwing: E = ValidationError
let result2 = try transform("hello", using: validateInput)