Parimate tavade tutvustamine - vigade käsitlemine

See on esimene artikkel õppetundide seeriast, mille olen õppinud selle paari aasta jooksul, mille jooksul olen Go-ga tootmises töötanud. Meil on Saltside Technologiesis tootmisel palju arvukalt Go-teenuseid (psst, ma võtan tööle mitu ametikohta Bangalores Saltside'i jaoks) ja ma haldan ka oma ettevõtet, kus Go on lahutamatu osa.

Katame laia valikut teemasid, nii suuri kui ka väikeseid.

Esimene teema, mida ma selles sarjas tahtsin katta, on vigade käsitlemine. See põhjustab uute Go arendajate jaoks sageli segadust ja tüütust.

Mõni taust - vealiides

Nii et oleme samal lehel. Nagu võite teada, tõrge rakenduses Go on lihtsalt midagi, mis tõrkeliidese rakendab. Liidese määratlus näeb välja selline:

tüüpi tõrkeliides {
    Viga () string
}

Seega saab veana kasutada kõike, mis rakendab stringi meetodit Error ().

Vigade kontrollimine

Vigastruktuuride kasutamine ja tüübi kontrollimine

Kui ma Go kirjutama hakkasin, siis tegin sageli veateadete võrdlusi, et näha, mis oli veatüüp (jah, piinlik mõelda, aga mõnikord tuleb edasiliikumiseks tagasi vaadata).

Parem lähenemine on veatüüpide kasutamine. Nii saate (muidugi) luua tõrkeliidese rakendavaid struktuure ja seejärel teha tüübi võrdluse lüliti avalduses.

Siin on näide vea rakendamisest.

tüüp ErrZeroDivision struct {
    sõnumistring
}
func NewErrZeroDivision (sõnumistring) * ErrZeroDivision {
    tagasi & ErrZeroDivision {
        teade: teade,
    }
}
func (e * ErrZeroDivision) viga () string {
    tagasta e-kiri
}

Nüüd saab seda viga kasutada nii.

func main () {
    tulemus, viga: = jaga (1,0, 0,0)
    kui eksid! = null {
        lüliti viga (tüüp) {
        juhtum * ErrZeroDivision:
            fmt.Println (viga.Error ())
        vaikimisi:
            fmt.Println ("Mis h * just juhtus?")
        }
    }
    fmt.Println (tulemus)
}
funktsiooni jagamine (a, b float64) (float64, viga) {
    kui b == 0,0 {
        tootlus 0.0, NewErrZeroDivision ("Ei saa nulliga jagada")
    }
    tagasi a / b, null
}

Siit leiate lingi Go Play täieliku näite jaoks. Pange tähele lüliti vea (tüübi) mustrit, mis võimaldab kontrollida erinevaid veatüüpe, mitte midagi muud (nt stringi võrdlus või midagi sarnast).

Vigade paketi kasutamine ja otsene võrdlus

Ülaltoodud lähenemisviisi saab kasutada ka vigade paketi abil. See lähenemisviis on soovitatav vigade kontrollimiseks paketi sees, kus vajate kiiret vigade esitamist.

var errNotFound = error.New ("Toodet ei leitud")
func main () {
    err: = getItem (123) // See viskaks errNotFound
    kui eksid! = null {
        lüliti viga {
        case errNotFound:
            log.Println ("Taotletud eset ei leitud")
        vaikimisi:
            log.Println ("Ilmnes tundmatu viga")
        }
    }
}

See lähenemisviis pole nii hea, kui vajate keerukamaid veaobjekte nt. veakoodid jne. Sel juhul peaksite looma oma tüübi, mis rakendab tõrkeliidest.

Kohene vigade käsitlemine

Mõnikord puutun kokku koodiga nagu allpool (kuid tavaliselt on seal rohkem kohevust):

func example1 () viga {
    viga: = kõne1 ()
    tagastamise viga
}

Siinkohal on asi selles, et viga ei käsitleta kohe. See on habras lähenemisviis, kuna keegi saab sisestada koodi err: = call1 () ja tagastamise vea vahele, mis rikuks kavatsuse, kuna see võib varjutada esimest viga. Kaks alternatiivset lähenemisviisi:

// Ahendage tagastamine ja viga.
func example2 () viga {
    tagasi kõne1 ()
}
// Tehke kohe pärast kõnet selget tõrkeotsingut.
func example3 () viga {
    viga: = kõne1 ()
    kui eksid! = null {
        tagastamise viga
    }
    tagasta null
}

Mõlemad ülaltoodud lähenemisviisid sobivad minuga. Nad saavutavad sama asja, mis on; kui keegi peab midagi lisama pärast kõnet1 (), peab ta hoolitsema vigade käsitlemise eest.

See on tänapäeva jaoks kõik

Olge kursis järgmise artikliga, mis käsitleb Go Parimaid Tavasid. Minge kangeks :).

func main () {
    err: = readArticle ("Parimate tavade tutvustamine - vigade käsitlemine")
    kui eksid! = null {
        ping ("@ sebdah")
    }
}