34 / 68

defer, panic and recover

Kechiktirish va Favqulodda holatlar

Go dasturlash tilida istisno va favqulodda vaziyatlarni boshqarish hamda resurslarni o'z vaqtida tozalash uchun uchta maxsus operator qo'llaniladi: defer, panic va recover.


1. Go defer operatori

defer operatori funksiyaning bajarilishini o'zi joylashgan tashqi funksiya to'liq o'z ishini tugatguniga qadar kechiktiradi:

example.go
package main

import "fmt"

func main() {
    // Ushbu chaqiruv eng oxirida bajariladi
    defer fmt.Println("Uch")

    fmt.Println("Bir")
    fmt.Println("Ikki")
}

Natija:

kod
Bir
Ikki
Uch

defer fmt.Println("Uch") birinchi yozilgan bo'lsa-da, main() tugashi arafasigacha kutib turadi. Bu fayllarni yopish (file.Close()) yoki ma'lumotlar bazasi ulanishlarini tozalashda juda qulay.


2. Bir nechta defer (LIFO tartibi)

Bitta funksiya ichida bir nechta defer ishlatilsa, ular LIFO (Last In, First Out — oxirgi kirgan birinchi chiqadi) steki tartibida teskari ketma-ketlikda ishlaydi:

example.go
package main

import "fmt"

func main() {
    defer fmt.Println("Bir")
    defer fmt.Println("Ikki")
    defer fmt.Println("Uch")
}

Natija:

kod
Uch
Ikki
Bir

3. Go panic operatori

panic operatori dastur tiklab bo'lmaydigan jiddiy xatoga duch kelganda dastur ijrosini darhol to'xtatish uchun ishlatiladi:

example.go
package main

import "fmt"

func division(num1, num2 int) {
    if num2 == 0 {
        // Dasturni darhol to'xtatamiz
        panic("Sonni nolga bo'lish mumkin emas!")
    } else {
        result := num1 / num2
        fmt.Println("Natija:", result)
    }
}

func main() {
    division(4, 2)
    division(8, 0) // Bu yerda dastur to'xtaydi
    division(2, 8) // Bu qatorga yetib bormaydi
}

Natija:

kod
Natija: 2
panic: Sonni nolga bo'lish mumkin emas!

4. Go recover operatori

panic yuz berganida butun dastur qulab tushishining oldini olish uchun recover() funksiyasidan foydalaniladi.

recover() operatori faqat defer qilingan funksiya ichida ishlashi mumkin. Agar dastur panic holatiga tushsa, recover() ushbu panic xabarini ushlab qoladi va dasturning keyingi kodlari odatiy davom etishini ta'minlaydi:

example.go
package main

import "fmt"

// Panic holatini ushlab qoluvchi funksiya
func handlePanic() {
    a := recover()

    if a != nil {
        fmt.Println("Xatolik ushlab qolindi (RECOVER):", a)
    }
}

func division(num1, num2 int) {
    // Panic yuz bersa ham handlePanic ishga tushadi
    defer handlePanic()

    if num2 == 0 {
        panic("Sonni nolga bo'lish mumkin emas!")
    } else {
        result := num1 / num2
        fmt.Println("Natija:", result)
    }
}

func main() {
    division(4, 2)
    division(8, 0) // Panic yuz beradi, ammo ushlanadi
    division(10, 2) // Dastur davom etadi!
}

Natija:

kod
Natija: 2
Xatolik ushlab qolindi (RECOVER): Sonni nolga bo'lish mumkin emas!
Natija: 5

E'tibor bering, division(8, 0) da panic sodir bo'lganiga qaramay, butun dastur to'xtab qolmadi va uchinchi chaqiruv division(10, 2) muvaffaqiyatli bajarildi.