Eng yaxshi amaliyotlarga o'ting - xatolar bilan ishlash

Bu men ishlab chiqarishda Go bilan birga ishlaganimda bir necha yil davomida o'rgangan darslarimdagi birinchi maqola. Biz Saltside Technologies-da ishlab chiqarishda juda ko'p Go xizmatlarini ko'rsatmoqdamiz (psst, men Saltside uchun Bangalorada bir nechta lavozimga yollayman) va men Go kompaniyasining ajralmas qismi bo'lgan o'z biznesimni olib boraman.

Biz katta va kichik mavzularni qamrab olamiz.

Ushbu seriyadagi birinchi mavzu - xatolar bilan ishlash. Ko'pincha Go yangi dasturchilarini chalkashtiradi va bezovta qiladi.

Ba'zi fon - xato interfeysi

Xuddi shuning uchun biz bitta sahifada turibmiz. Bilishingiz mumkin, Go-dagi xato shunchaki xato interfeysini amalga oshiradigan narsa. Bu interfeys ta'rifi quyidagicha:

xato interfeysi turi {
    Xato () qatori
}

Xato () satr usulini amalga oshiradigan har qanday narsa xato sifatida ishlatilishi mumkin.

Xatolarni tekshirish

Xatolar chizmalaridan foydalanish va turlarni tekshirish

Men Go yozishni boshlaganimda, xato turini aniqlash uchun xato xabarlarini ko'p taqqoslab turardim (ha, o'ylashdan uyalaman, lekin ba'zan oldinga borish uchun orqaga qarash kerak).

Yaxshiroq yondashuv - xato turlaridan foydalanish. Shunday qilib, siz (albatta) xato interfeysini amalga oshiradigan chiziqlar yaratishingiz va keyin kommutatsiya bayonotida turlarni taqqoslashingiz mumkin.

Xatolarni amalga oshirishga misol.

turi ErrZeroDivision strukturasi {
    xabarlar qatori
}
funktsiya NewErrZeroDivision (xabarlar qatori) * ErrZeroDivision {
    return & ErrZeroDivision {
        xabar: xabar,
    }
}
func (e * ErrZeroDivision) Xato () string {
    e.message-ni qaytaring
}

Endi bu xato shu kabi ishlatilishi mumkin.

func main () {
    natija, xato: = bo'lmoq (1.0, 0.0)
    agar adashsangiz! = nil {
        almashtirish xatosi (turi) {
        case * ErrZeroDivision:
            fmt.Println (xato xatosi ())
        standart:
            fmt.Println ("h * hozirgina nima bo'ldi?")
        }
    }
    fmt.Println (natija)
}
funktsiya bo'linishi (a, b float64) (float64, xato) {
    agar b == 0.0 {
        return 0.0, NewErrZeroDivision ("Nolga bo'lish mumkin emas")
    }
    a / b, nilni qaytaring
}

Bu erda to'liq misol uchun Go Play havolasi mavjud. Boshqa turdagi (masalan, simlarni taqqoslash yoki shunga o'xshash) emas, balki har xil turdagi xatolar turlarini tekshirishga imkon beradigan kommutator xatosi (turi) naqshiga e'tibor bering.

Xatolar to'plamidan foydalanish va to'g'ridan-to'g'ri taqqoslash

Yuqoridagi yondashuv alternativa xatolar to'plamidan foydalanib ko'rib chiqilishi mumkin. Ushbu yondashuv sizga tezda xatolarni ko'rsatishni talab qiladigan paketdagi xatolarni tekshirish uchun tavsiya etiladi.

var errNotFound = error.New ("Element topilmadi")
func main () {
    err: = getItem (123) // Bu errNotFoundni tashlaydi
    agar adashsangiz! = nil {
        switch err {
        case errNotFound:
            log.Println ("Talab qilingan narsa topilmadi")
        standart:
            log.Println ("Noma'lum xato yuz berdi")
        }
    }
}

Agar sizga masalan murakkabroq xato ob'ektlari kerak bo'lsa, ushbu yondashuv kamroq foydali bo'ladi. xato kodlari va boshqalar. Bunday holda siz xato interfeysini amalga oshiradigan o'z turingizni yaratishingiz kerak.

Darhol xatolar bilan ishlov berish

Ba'zan men quyidagi kabi kodni uchrataman (lekin odatda ko'proq to'lqin bilan ..):

func example1 () xatosi {
    xato: = call1 ()
    qaytish xatosi
}

Gap shundaki, xato darhol hal qilinmaydi. Bu nozik yondashuv, chunki kimdir err: = call1 () va qaytish xatosi o'rtasida kodni kiritishi mumkin, bu niyatni buzishi mumkin, chunki bu birinchi xatoga soya solishi mumkin. Ikkita alternativ yondashuv:

// Qaytish va xatoni buzish.
func example2 () xatosi {
    qaytish qo'ng'iroq1 ()
}
// Qo'ng'iroqda darhol xatolarni aniq ko'rib chiqing.
func example3 () xatosi {
    xato: = call1 ()
    agar adashsangiz! = nil {
        qaytish xatosi
    }
    nil qaytaring
}

Yuqoridagi ikkala yondashuv men uchun yaxshi. Ular bir narsaga erishadilar, ya'ni; agar kimdir qo'ng'iroqdan keyin biror narsani qo'shishi kerak bo'lsa (1), ular xatolar bilan ishlashda ehtiyot bo'lishlari kerak.

Hozir hammasi shu

Eng yaxshi amaliyotlar haqida keyingi maqolani tinglang. Kuchli boring :).

func main () {
    err: = readArticle ("Eng yaxshi amaliyotlar - xatolar bilan ishlash")
    agar adashsangiz! = nil {
        ping ("@ sebdah")
    }
}