Throw/Throws — bu nədir, istisna atma operatorları və mobil inkişafda necə işləyir

Müəllif: IT Sectr Dərc olunub: 2026-05-26 Oxuma vaxtı: 9 dəq

Throw və Throws — proqramlaşdırma dillərində istisnaların atılması və bəyan edilməsi mexanizmləri. Throw operatoru funksiyanın normal icrasını dayandırır və xəta obyektini çağırış stekində yuxarı ötürür. Throws açar sözü funksiya imzasında çağıran tərəfi xəta ehtimalı barədə xəbərdar edir, kodu proqnozlaşdırıla bilən edir. Kotlin Documentation (2026)-ya görə, Kotlin-də throw ifadə (expression)dir, təlimat (instruction) deyil, bu da onun when blokları və elvis operatoru daxilində istifadəsinə imkan verir.

Əsas məqamlar

  • Throw — funksiyanın icrasını dayandıran və xəta obyektini çağırış stekində yuxarı ötürən operator
  • Throws — funksiya imzasında funksiyanın istisna ata biləcəyini bəyan edən açar söz
  • Swift-də funksiya throws ilə işarələnir, çağırış try/try?/try! tələb edir, throw isə Error protokolunu reallaşdıran istənilən tipi qəbul edir
  • Kotlin-də throw — Nothing tipli ifadə, throws mövcud deyil (bütün istisnalar uncheckeddir)
  • İstifadəçi xətaları catch-də rahat emal üçün enum (Swift) və ya sealed class (Kotlin) vasitəsilə yaradılır

Throw və Throws nədir?

Throw — proqramın icra nöqtəsində istisna yaradan operatordur. Throw ilə qarşılaşdıqda, cari icra axını dərhal dayandırılır və idarəetmə çağırış stekində ən yaxın catch işləyicisinə ötürülür. Əgər işləyici tapılmazsa, proqram xəta ilə dayanır. Mobil inkişafda throw, cari abstraksiya səviyyəsində emal edilə bilməyən xətaları bildirmək üçün istifadə olunur — məsələn, serverdən səhv cavab, şəbəkənin olmaması və ya yanlış arqumentlər.

Throws — funksiya imzasında modifikator (əsasən Swift-də), funksiyanın xəta ata biləcəyini bəyan edir. Bu, Swift-də checked errors mexanizminin bir hissəsidir: çağıran tərəf xətanı do-catch, try?, try! vasitəsilə emal etməli və ya öz funksiyasını throws ilə işarələyərək daha da ötürməlidir (propagation). Kotlin və Java-da throws da mövcuddur, lakin Kotlin onu artıq hesab edir — Kotlin-də bütün istisnalar uncheckeddir, yəni sintaktik məcburiyyət olmadan emal edilməyə bilər. Apple Swift Documentation (2026)-ya görə, Swift-də throws — funksiya tipində xəta ehtimalını açıq şəkildə bəyan etməyin yeganə yoludur ki, bu da API kontraktlarını tərtibatçı üçün şəffaf edir.

Throw və throws arasındakı fərq əsaslıdır: throw — hərəkətdir (runtime-da istisnanın atılması), throws — bəyandır (compile-time kontraktı). Throws olmayan funksiya throw istifadə edə bilməz — Swift kompilyatoru xəta verəcək. Throws olan funksiya throw istifadə etməyə bilər — bu icazə verilir, lakin mənasızdır. Bu bölgü throw/throws-u API dizaynında güclü alətə çevirir, burada xəta kontraktı funksiyanın imzasında onu çağırmazdan əvvəl görünür.

Swift-də Throw

Swift-də throw operatoru Error protokolunu reallaşdıran istənilən tipi qəbul edir. Ən çox bu, müxtəlif xəta növləri üçün case-lər olan enumdur. Swift Java üslubunda checked exceptions-u dəstəkləmir — bunun əvəzinə funksiya tipi throws ilə işarələnir, emal isə çağıran tərəfin üzərinə düşür. Bu, Swift-də throw-u daha çevik, eyni zamanda tərtibatçı üçün daha məsuliyyətli edir.

Error protokolu və xəta tipləri

Error protokoluna uyğun gələn istənilən tip throw vasitəsilə atıla bilər. Ən çox tərtibatçılar sadə xətalar üçün assosiativ dəyərləri olmayan case-lər və ya kontekst ötürmək üçün associated values olan enum istifadə edirlər. Swift xətanın enum olmasını tələb etmir — Error-u reallaşdıran struct və ya class istifadə edilə bilər, lakin enum işləyici tərəfdə exhaustive switch sayəsində daha üstündür. Kompilyator do-catch-də bütün case-lərin emal edildiyini yoxlayır.

swift
enum AuthError: Error {
    case invalidCredentials
    case tokenExpired
    case accountLocked(remainingMinutes: Int)
}

func login(username: String, password: String) throws -> Session {
    guard isValid(username) else {
        throw AuthError.invalidCredentials
    }
    let response = try api.authenticate(username, password)
    if response.isLocked {
        throw AuthError.accountLocked(
            remainingMinutes: response.lockDuration
        )
    }
    return Session(token: response.token)
}

AuthError üç ssenarini təyin edir: etibarsız giriş məlumatları, müddəti bitmiş token və remainingMinutes assosiativ dəyəri ilə bloklanmış hesab. login funksiyası throws olaraq bəyan edilmişdir — kompilyator onu try vasitəsilə çağırmağı tələb edir. Funksiya daxilində throw iki yerdə istifadə olunur: etibarsız username olduqda və hesab bloklandıqda. Assosiativ dəyər accountLocked istifadəçiyə konkret məlumat ötürməyə imkan verir — blokun açılması üçün neçə dəqiqə gözləmək lazımdır. Bu yanaşma bloklama statusunu yoxlamaq üçün ayrıca API endpoint-lərinə ehtiyacı aradan qaldırır.

Kotlin-də Throw

Kotlin-də throw — təlimat deyil, Nothing tipli ifadədir (expression). Bu o deməkdir ki, throw təyinatın sağ tərəfində, when ifadələri daxilində və elvis operatoru ?: daxilində istifadə edilə bilər. Nothing tipi — Kotlin-də bütün tiplərin xüsusi alt tipidir ki, bu da throw-un istənilən tipdə dəyər tələb olunan yerlərdə istifadəsinə imkan verir. Kompilyator başa düşür ki, throw-dan sonra icra davam etmir və bu hal üçün budaq tələb etmir.

Nothing tipi və onun kompozisiyada rolu

Nothing — Kotlin-də bütün mümkün tiplərin alt tipi olan unikal tipdir. Nothing qaytaran funksiya (məsələn, TODO()) heç vaxt normal şəkildə tamamlanmır — ya həmişə istisna atır, ya da sonsuz döngüyə girir. Bu, throw-u dəyər tələb olunan yerlərdə istifadə üçün təbii namizəd edir: elvis operatoru, else-siz when, dəyişənin inisializasiyası. Əgər throw when budağındadırsa, kompilyator budağın Nothing-ə apardığını başa düşür və bu budaq üçün return və ya else tələb etmir.

kotlin
data class Config(val apiUrl: String, val timeoutSec: Int)

class ConfigParser {
    fun parse(json: String): Config {
        val obj = JSONObject(json)
        val url = obj.optString("apiUrl")
            ?: throw IllegalArgumentException("apiUrl is required")
        val timeout = obj.optInt("timeoutSec", 30)
        return Config(url, timeout)
    }

    fun getErrorMessage(code: Int): String {
        return when (code) {
            404 -> "Not found"
            500 -> "Server error"
            else -> throw IllegalArgumentException("Unknown code: $code")
        }
    }
}

Birinci nümunədə throw elvis operatoru ?: daxilində istifadə olunur: əgər apiUrl sahəsi JSON-da yoxdursa, throw ifadəsi dərhal icranı dayandırır və IllegalArgumentException atır. Nothing tipi kompilyatora sağ tərəfin tipini String olaraq çıxarmağa imkan verir (elvis String gözləyir, throw Nothing tipinə malikdir, Nothing String-in alt tipidir). İkinci nümunədə throw when ifadəsi daxilindədir: əgər kod heç bir tanınana uyğun gəlmirsə, istisna atılır. Kompilyator başa düşür ki, throw-dan sonra kod əlçatmazdır, buna görə də funksiyanın qaytardığı String tipi pozulmur.

Funksiya imzasında Throws və rethrows

Swift-də throws parametr siyahısından sonra və qaytarılan tipin oxundan əvvəl göstərilir. Throws olan funksiya yalnız digər throws funksiyalarını do-catch daxilində və ya try? ilə çağıra bilər. Əgər throws funksiyası xətanı emal etmirsə, onu çağıran tərəfə ötürür. Swift həmçinin rethrows-u dəstəkləyir — throws domkiliyini qəbul edən və onun xətasını ötürən yüksək səviyyəli funksiyalar üçün modifikator. Rethrows o deməkdir ki, funksiya xətanı yalnız ötürülən domkilik onu atdıqda atır — funksiyanın özü xəta yaratmır.

swift
func mapValues<T>(
    _ array: [T],
    transform: (T) throws -> U
) rethrows -> [U] {
    var result = [U]()
    for element in array {
        result.append(try transform(element))
    }
    return result
}

// Throws-qapanması ilə istifadə
let parsed = try mapValues(jsonStrings) { str in
    let data = Data(str.utf8)
    return try JSONDecoder().decode(Item.self, from: data)
}

Rethrows mapValues funksiyasının çevik olmasına imkan verir: həm throws domkiliklərini, həm də adi olanları qəbul edir. Əgər throws domkiliyi ötürülərsə, mapValues çağırışı try tələb edir; adidirsə — try tələb olunmur. Bu, rethrows-u Swift-in standart kitabxanasında map, filter, reduce kimi yüksək səviyyəli funksiyalar üçün ideal edir. Apple tövsiyəsi: throws domkiliklərini qəbul edən və yeganə xəta mənbəyi bu domkilik olan API-lər üçün rethrows istifadə edin. Əgər funksiya öz xətasını ata bilirsə, throws istifadə edin.

Checked vs unchecked istisnaları

Swift throws checked exceptions-a (Java-dakı kimi) daha yaxındır — atılan xətalar imzada bəyan edilir. Kotlin və Dart unchecked istisnalarından istifadə edir — throws imzada tələb olunmur. Fərq əsaslıdır: checked tərtibatçını emal etməyə məcbur edir (təhlükəsiz, lakin daha uzun), unchecked sərbəstlik verir, lakin xətanı emal etməyi unutmaq riskini artırır. Swift throws üçün checked, Kotlin bütün istisnalar üçün unchecked seçmişdir. Hər iki yanaşmanın üstünlükləri var: Swift dil səviyyəsində daha etibarlıdır, Kotlin daha yığcam və funksional çevrilmə zəncirlərində daha rahatdır.

Xüsusi xəta tipləri

Mobil tətbiqlərdə strukturlaşdırılmış xəta emalı üçün əsas Exception və ya Error istifadə etmək əvəzinə öz xəta tiplərinizi yaratmaq tövsiyə olunur. Swift-də bunun üçün Error protokolu ilə enum, Kotlin-də Throwable-dan (və ya Exception-dan) miras alan sealed class, Dart-da Exception-dan miras alan class istifadə olunur. Xüsusi tiplər xətaları kateqoriyalara görə qruplaşdırmağa və assosiativ məlumat ötürməyə imkan verir.

DilXəta tipiXüsusiyyət
Swiftenum: Error { ... }Assosiativ dəyərlər, catch-də exhaustive switch
Kotlinsealed class : Throwable()Sahələri olan data class, when ifadəsi
Dartclass implements ExceptionMessage sahəsi, catch-də on-klauzulası
Javaclass extends ExceptionChecked vs unchecked, imzada məcburi throws

Xüsusi xətaları layihələşdirərkən qaydaya əməl edin: bir xəta — bir ssenari. Müxtəlif səbəbləri String message bayrağı ilə bir tipdə birləşdirməyin — hər ssenari üçün ayrıca case/lar/alt siniflər yaradın. Bu, çağıran tərəfə hər bir hadisəni sətir müqayisəsi ilə deyil, pattern matching (when/switch) vasitəsilə emal etməyə imkan verəcək. Swift-də bu exhaustive checking verir — kompilyator NetworkError enum-unun hansısa case-i emal edilməyibsə xəbərdarlıq edəcək.

Kotlin-də xüsusi xəta nümunəsi

kotlin
sealed class NetworkError(val message: String) : Throwable(message) {
    data class Timeout(val durationMs: Long) :
        NetworkError("Request timed out after ${durationMs}ms")
    data class HttpError(val code: Int, val body: String?) :
        NetworkError("HTTP $code")
    data class NoConnection(val cause: IOException) :
        NetworkError("No internet connection")
}

Sealed class NetworkError Throwable-dan (Kotlin-də standart istisna tipi) miras alır. Hər bir alt sinif öz sahələri olan data class-dır: Timeout millisaniyələrlə vaxt aşımı müddətini ehtiva edir, HttpError — cavab kodu və məzmunu, NoConnection — orijinal IOException-u. Bu dizayn hər bir xətanı when vasitəsilə tam əhatəli şəkildə emal etməyə imkan verir (yeni alt sinif əlavə etdikdə, kompilyator bütün when ifadələrini yeniləməyə məcbur edəcək).

Swift-də Try, try? və try!

Swift throws funksiyalarını çağırmaq üçün üç variant təklif edir, hər biri öz təhlükəsizlik kontraktına malikdir. try — standart üsul: do-catch tələb edir və ya throws funksiyası daxilində olmağı tələb edir. try? xətanı nil-ə çevirir — nəticə opsional olur, xəta olduqda nil qaytarılır, tip T-dən T?-ə dəyişir. try! — emal olmadan məcburi icra: əgər xəta atılırsa, proqram çökür. try! yalnız xətanın mümkünsüz olduğuna tam əmin olduqda istifadə edin (məsələn, açıq-aydın düzgün məlumatlar).

swift
let configPath = Bundle.main.path(forResource: "config", ofType: "json")!

// try? — opsional nəticə
let data = try? Data(contentsOf: URL(fileURLWithPath: configPath))
let json = try? JSONSerialization.jsonObject(with: data ?? Data())

// try! — zəmanətli uğur (yalnız əmin olduqda)
let decoder = JSONDecoder()
let defaultConfig = try! decoder.decode(
    Config.self,
    from: Config.defaultJSON
)

// try — standart emal
do {
    let user = try fetchUser()
    showUser(user)
} catch let error as NetworkError {
    showRetryAlert(error.message)
}

Nümunədə try! tətbiqin bundle-ına daxil edilmiş açıq-aydın düzgün JSON üçün istifadə olunur — düzgün buraxılış zamanı deşifrə xətası mümkün deyil. try? konfiqurasiya faylını oxumaq üçün tətbiq edilir — fayl yoxdursa və ya zədələnibsə, tətbiq çökmək əvəzinə standart dəyərlərdən istifadə edir. try do-catch-də şəbəkə sorğuları üçün istifadə olunur, burada xəta gözlənilir və istifadəçi reaksiyası tələb edir. Tövsiyə: production kodunda try!-dən çəkinin — yalnız quraşdırma mərhələsində yoxlanılmış sabit məlumatlar üçün istisna edin.

Tez-tez verilən suallar

Swift-də throw və throws arasında fərq nədir?

Throw — proqramın icrası zamanı xətanı atan, axını dayandıran operatordur. Throws — funksiyanın xəta ata biləcəyini bəyan edən funksiya imzası modifikatorudur. Throws olmayan funksiya throw istifadə edə bilməz. Throws compile-time kontraktıdır, throw isə runtime hərəkətidir.

Niyə Kotlin-də throws yoxdur?

Kotlin unchecked exceptions fəlsəfəsinə əməl edir: bütün istisnalar sintaktik məcburiyyət olmadan emal edilməyə bilər. Kotlin tərtibatçıları hesab edir ki, Java-da throws həddindən artıq try-catch bloklarına və boş catch vasitəsilə checked exceptions-un göz ardı edilməsinə səbəb olur. Kotlin-in Nothing tipi throw-u ifadə kimi istifadə etməyə imkan verir, throws-u daha çevik bir üsulla əvəz edir.

Swift-də try! nə vaxt istifadə edilməlidir?

try! yalnız xətanın mümkünsüz olduğuna tam əmin olduqda icazəlidir: bundle-dan açıq-aydın düzgün JSON, sabit məlumatlar, düzgün URL sxemləri. Production kodunda try! — istisna, qayda deyil. try? geri dönüş dəyəri olan opsional ssenarilər üçün, try do-catch ilə isə məcburi xəta emalı üçün üstünlük təşkil edir.

Swift-də rethrows nədir?

Rethrows — throws domkiliklərini qəbul edən funksiyalar üçün modifikator. Rethrows olan funksiya xətanı yalnız ötürülən domkilik onu atdıqda atır. Bu, yüksək səviyyəli funksiyaların (map, filter) həm throws, həm də non-throws domkilikləri ilə çağıran tərəfdə məcburi try olmadan işləməsinə imkan verir.

Catch bloku daxilində xəta atmaq mümkündürmü?

Bəli, catch daxilində xətanı başqa tipə sararaq və ya kontekst əlavə edərək stekdə yuxarı ötürmək üçün throw istifadə edilə bilər. Buna error chaining və ya rethrow deyilir. Swift-də bunun üçün catch daxilində daha bir throw kifayətdir, Kotlin-də — catch bloku daxilində throw. finally bloku idarəetmənin daha da ötürülməsindən əvvəl icra olunacaq.

Nəticə

  • Throw — cari axını dayandıran və xəta obyektini stekdə yuxarı ötürən istisna atma operatoru
  • Throws — funksiya imzasında xəta ehtimalı haqqında compile-time bəyannaməsi, Swift-də məcburi, Kotlin-də mövcud deyil
  • Swift-də throw enum: Error qəbul edir, funksiya throws ilə işarələnir, try / try? / try! vasitəsilə çağırılır
  • Kotlin-də throw — Nothing tipli ifadə, when, elvis operatoru və təyinatda istifadəyə imkan verir
  • Rethrows Swift-də yüksək səviyyəli funksiyalara xətaları yalnız ötürülən domkiliklərdən ötürməyə imkan verir
  • Xüsusi xətalar ətraflı məlumat üçün assosiativ dəyərlərlə enum (Swift) və ya sealed class (Kotlin) vasitəsilə yaradılır
  • Xəta tiplərini pattern matching vasitəsilə rahat emal üçün „bir case — bir ssenari“ prinsipi ilə layihələşdirin

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun