Skip to content

Xatolarni boshqarish

Go dasturlash tilida exceptions (istisnolar) tushunchasi mavjud emas. Buning o'rniga, xatoliklarni qayta ishlash return qiymat orqali amalga oshiriladi.

Go dasturlash tilida funksiyalar odatda ikkita qiymat qaytaradi:

  • Asosiy natija
  • Xatolik obyekti (error)

Agar xatolik yuz bersa, funksiyaning ikkinchi qiymati error interfeysining implementatsiyasi bo'ladi. Agar xatolik bo'lmasa, error nil bo'ladi.

Xatolikni qayta ishlashga misol

package main

import (
    "fmt"
)

func bul(a, b int) (int, error) {
    if b == 0 {
        return 0, fmt.Errorf("nolga bo'lish mumkin emas")
    }
    return a / b, nil
}

func main() {
    c, err := bul(1, 3)
    if err != nil {
        fmt.Println("Xatolik:", err)
    } else {
        fmt.Println("Natija:", c)
    }

    d, err := bul(1, 0)
    if err != nil {
        fmt.Println("Xatolik:", err)
    } else {
        fmt.Println("Natija:", d)
    }
}

Natija:

Natija: 0
Xatolik: nolga bo'lish mumkin emas
Boshqa tillarda bo'lgani kabi try-catch bloki yo'qligi sababli, har bir funksiyada xatoliklarni tekshirish va qayta ishlash talab qilinadi. Shu sababli, Go ning xatoliklarni qayta ishlash usuli soddaroq, ammo ko'proq kod yozishni talab qiladi.

panic va recover

  • panic dastur ishini favqulodda to'xtatish uchun ishlatiladigan funksiya. U odatda tiklab bo'lmaydigan xatolar yuz berganda chaqiriladi.
  • recover panikani ushlab olish va dastur ishini davom ettirish imkonini beradi. Bu odatda defer bilan ishlaydi.
  • defer bu Goda funksiya ichida kechiktirilgan chaqiruvlarni bajarish uchun ishlatiladigan kalit so'z. U funksiyaning bajarilishi tugashidan oldin chaqiriladi, hatto funksiyada return yoki panic bo'lsa ham.

defer qanday ishlaydi?

Agar funksiyada defer ishlatilsa, u chaqirilgan qator bajarilgan bo'lsa ham, haqiqiy bajarilishi funksiya yakunida amalga oshiriladi.

package main

import "fmt"

func main() {
    defer fmt.Println("Bu xabar oxirida chiqariladi")
    fmt.Println("Bu xabar birinchi chiqariladi")
}

Natija:

Bu xabar birinchi chiqariladi
Bu xabar oxirida chiqariladi

defer qatori oldin yozilgan bo'lsa ham, u main() funksiyasi tugagandan keyin bajarildi.

bir nechta deferlar

Agar bir nechta defer ishlatilsa, ular LIFO (Last In, First Out) tartibida bajariladi.

package main

import "fmt"

func main() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("main() funksiyasi ishlamoqda")
}

Natija:

main() funksiyasi ishlamoqda
3
2
1

defer odatda recover() bilan birga ishlatiladi, bu esa panic yuzaga kelgan holatlarda dasturni to'xtatib qo'ymaslikka yordam beradi va fayllar bilan ishlashda ham fayllarni yopish uchun defer yaxshi imkoniyat hisoblanadi.

panic va recover() ga misol

package main

import "fmt"

func main() {
    defer func() {
        r := recover()
        if r != nil {
            fmt.Println("Panikadan tiklanish:", r)
        }
    }()

    panic("Jiddiy xatolik yuz berdi!")
}

Ushbu kodini bosqichma-bosqich tahlil qilamiz:

1-qadam: defer chaqiriladi - defer orqali anonim (func() { ... }) funksiya ro'yxatga olinadi. - defer bajarilishi kechiktiriladi va main() funksiyasining oxirida chaqiriladi.

2-qadam: panic chaqiriladi - panic("Jiddiy xatolik yuz berdi!") chaqiriladi. - Bu dasturni favqulodda to'xtatadi. - Ammo, defer qoidasi bo'yicha, kechiktirilgan funksiya bajariladi.

3-qadam: recover() chaqiriladi - recover() faqat defer ichida ishlaydi va agar panic bo'lsa, uning xabarini oladi. - Agar panic bo'lmaganida, recover() nil qaytargan bo'lar edi.

4-qadam: panic borligini tekshirish

if r != nil {
  • Agar panic bo'lsa, recover() uning xabarini qaytaradi ("Jiddiy xatolik yuz berdi!").
  • Shart true bo'ladi va fmt.Println("Panikadan tiklanish:", r) bajariladi.

5-qadam: Dastur davom etadi

  • panic ushlangani uchun dastur to'xtamaydi va ishlashda davom etadi.

Natija:

Panikadan tiklanish: Jiddiy xatolik yuz berdi!

Natija shuni anglatadiki, panic() chaqirilgan bo'lsa ham, recover() uni ushlab olgan va dasturning ishlashi davom etgan.

Xatolik yuzaga kelishi mumkin bo'lgan holatlar

Agar recover() defer ichida bo'lmasa, panic dasturni butunlay to'xtatadi.

package main

import "fmt"

func main() {
    r := recover()  // Bu yerda recover() ishlamaydi
    if r != nil {
        fmt.Println("Panikadan tiklanish:", r)
    }

    panic("Jiddiy xatolik yuz berdi!")  // Dastur to'xtab qoladi
}

Natija:

panic: Jiddiy xatolik yuz berdi!

Info

recover() faqat defer ichida ishlaydi.