Go Best Practices - Napake pri ravnanju

To je prvi članek v nizu lekcij, ki sem se jih naučil v nekaj letih, ko sem sodeloval z Go v proizvodnji. V Saltside Technologies vodimo veliko Go storitev, ki se ukvarjajo s proizvodnjo (psst, najem več položajev v Bangaloreju za Saltside), vodim pa tudi svoje podjetje, kjer je Go sestavni del.

Obsegali bomo široko paleto predmetov, velikih in majhnih.

Prva tema, ki sem jo želel obravnavati v tej seriji, je ravnanje z napakami. Novi razvijalci Go pogosto povzročajo zmedo in sitnost.

Nekaj ​​ozadja - Vmesnik napak

Tako, da smo na isti strani. Kot morda veste, je napaka v Go preprosto preprosto vse, kar izvaja vmesnik za napake. Tako izgleda definicija vmesnika:

tip vmesnika napake {
    Napaka ()
}

Torej, karkoli, ki izvaja metodo niza Error (), se lahko uporabi kot napaka.

Preverjanje napak

Uporaba struktur napak in preverjanje vrste

Ko sem začel pisati Pojdi, sem pogosto delal vrvice primerjav sporočil o napakah, da sem videl, kakšna je vrsta napake (da, nerodno je razmišljati, a včasih se je treba ozreti nazaj, da greš naprej).

Boljši pristop je uporaba vrst napak. Tako lahko (seveda) ustvarite strukture, ki izvajajo vmesnik napak in nato naredite primerjavo v stavku stikala.

Tu je primer izvajanja napake.

vrsta ErrZeroDivision structure {
    sporočilni niz
}
func NewErrZeroDivision (sporočilo niz) * ErrZeroDivision {
    return & ErrZeroDivision {
        sporočilo: sporočilo,
    }
}
funkc (e * ErrZeroDivision) Napaka () niz {
    vrnite e.message
}

Zdaj je mogoče to napako uporabiti tako.

func main () {
    rezultat, napaka: = delitev (1,0, 0,0)
    če je napaka! = nič {
        napaka stikala (tip) {
        primer * ErrZeroDivision:
            fmt.Println (err.Error ())
        privzeto:
            fmt.Println ("Kaj se je h * pravkar zgodilo?")
        }
    }
    fmt.Println (rezultat)
}
func deliti (a, b float64) (float64, napaka) {
    če je b == 0,0 {
        vrne 0,0, NewErrZeroDivision ("Ne morem deliti na nič")
    }
    vrniti a / b, nič
}

Tu je povezava Go Play za celoten primer. Opazite vzorec napake stikala (vrste), ki omogoča preverjanje različnih vrst napak, namesto česa drugega (npr. Primerjava niza ali kaj podobnega).

Uporaba paketa napak in neposredna primerjava

Zgornji pristop je mogoče alternativno uporabiti s pomočjo napak. Ta pristop je priporočljiv za preverjanje napak v paketu, kjer potrebujete hitro zastopanje napak.

var errNotFound = napake.Novo ("Elementa ni mogoče najti")
func main () {
    err: = getItem (123) // To bi vrglo errNotFound
    če je napaka! = nič {
        preklopi napako {
        Zadeva errNotFound:
            log.Println ("Zahtevani element ni najden")
        privzeto:
            log.Println ("zgodila je neznana napaka")
        }
    }
}

Ta pristop je manj dober, kadar potrebujete bolj zapletene predmete napak z npr. kode napak itd. V tem primeru ustvarite svoj tip, ki izvaja vmesnik napak.

Takoj ravnanje z napakami

Včasih naletim na kodo, kot je spodaj (ponavadi z več puha okrog ..):

Func example1 () napaka {
    napaka: = call1 ()
    vrniti napako
}

Bistvo tukaj je, da se napaka ne odpravi takoj. To je krhek pristop, saj lahko nekdo vstavi kodo med err: = call1 () in return err, kar bi pretrgalo namen, saj lahko to zasenči prvo napako. Dva nadomestna pristopa:

// Strni vrnitev in napako.
Func example2 () napaka {
    povratni klic1 ()
}
// Naredite izrecno obravnavanje napak takoj po klicu.
Func example3 () napaka {
    napaka: = call1 ()
    če je napaka! = nič {
        vrniti napako
    }
    vrniti nič
}

Oba zgornja pristopa sta mi v redu. Dosežejo isto, kar je; če mora nekdo nekaj dodati po call1 (), mora poskrbeti za ravnanje z napakami.

To je vse za danes

Spremljajte naslednji članek o Go Best Practices. Pojdi močno :).

func main () {
    napaka: = readArticle ("Najboljše prakse - obravnavanje napak")
    če je napaka! = nič {
        ping ("@ sebdah")
    }
}