A legjobb gyakorlatok bevezetése - Hibakezelés

Ez az első cikk az órák sorozatában, amelyet megtanultam azon pár év alatt, amikor a Go-val együtt dolgoztam a termelésben. Számos Go szolgáltatást működtetünk a Saltside Technologies gyártásában (psst; több pozíciót bérelek a Bangalore-ban a Saltside számára), és a saját vállalkozásomat is működtetom, ahol a Go szerves része.

Tárgyak széles skáláját fedjük le, nagy és kicsi.

Az első téma ebben a sorozatban a hibakezelés volt. Ez gyakran zavart és bosszantást okoz az új Go fejlesztők számára.

Néhány háttér - a hiba felülete

Csak ugyanazon az oldalon vagyunk. Mint lehet, hogy tudod, hogy a Go alkalmazásban előforduló hiba egyszerűen bármi megvalósítja a hiba felületet. Így néz ki a felület meghatározása:

típus hiba interfész {
    Hiba () karakterlánc
}

Tehát bármi, ami a Error () karakterlánc módszerét valósítja meg, hibaként használható.

Hibakeresés

Hibastruktúrák használata és típusvizsgálat

Amikor elkezdtem írni a Go-t, gyakran összehasonlítottam a hibaüzeneteket, hogy megnézem, mi a hiba típusa (igen, kínos gondolkodni, de néha vissza kell nézni, hogy továbblépjek).

Jobb megközelítés a hibatípusok használata. Tehát (természetesen) létrehozhat olyan struktúrákat, amelyek végrehajtják a hiba felületet, majd elvégzik a típus-összehasonlítást a kapcsoló utasításban.

Íme egy példa a hiba végrehajtására.

típusú ErrZeroDivision struct {
    üzenet karakterlánc
}
func NewErrZeroDivision (üzenet karakterlánc) * ErrZeroDivision {
    visszatérés & ErrZeroDivision {
        üzenet: üzenet,
    }
}
func (e * ErrZeroDivision) Hiba () karakterlánc {
    vissza e-üzenet
}

Most ezt a hibát így lehet felhasználni.

func main () {
    eredmény, hib: = ossza (1,0, 0,0)
    ha hibás! = nulla {
        kapcsoló hibája (típus) {
        eset * ErrZeroDivision:
            fmt.Println (err.Error ())
        alapértelmezett:
            fmt.Println ("Mi történt most? *")
        }
    }
    fmt.Println (eredmény)
}
func split (a, b float64) (float64, hiba) {
    ha b == 0,0 {
        visszatérés 0.0, NewErrZeroDivision ("Nem osztható nullával")
    }
    vissza a / b, nulla
}

Itt található a Go Play link a teljes példához. Vigyázzon a kapcsoló hibájának (típusának) mintájára, amely lehetővé teszi a különféle hibatípusok ellenőrzését, nem pedig valami mást (például karakterlánc-összehasonlítás vagy valami hasonló).

A hibacsomag használata és a közvetlen összehasonlítás

A fenti megközelítés alternatívaként a hibacsomag segítségével is kezelhető. Ez a megközelítés javasolt a csomagon belüli hibaellenőrzésekhez, ahol gyors hibareprezentációra van szükség.

var errNotFound = hibák.Új ("Az elem nem található")
func main () {
    err: = getItem (123) // Ez az errNotFound fájlt okozná
    ha hibás! = nulla {
        kapcsoló hibája {
        case errNotFound:
            log.Println ("A kért terméket nem található")
        alapértelmezett:
            log.Println ("Ismeretlen hiba történt")
        }
    }
}

Ez a megközelítés kevésbé jó, ha összetettebb hibaobjektumokra van szükség pl. hibakódok stb. Ebben az esetben létre kell hoznia a saját típusát, amely végrehajtja a hiba felületet.

Azonnali hibakezelés

Időnként az alábbiak szerint találkozom a kóddal (de általában több bolyhos körül ..):

func example1 () hiba {
    err: = hívás1 ()
    visszatérési hiba
}

A lényeg az, hogy a hibát nem azonnal kezelik. Ez törékeny megközelítés, mivel valaki beilleszthet kódot az err: = call1 () és a visszatérési hiba közé, ami megtörné a szándékot, mivel ez árnyékolhatja az első hibát. Két alternatív megközelítés:

// A visszaadás és a hiba összecsukása.
func example2 () hiba {
    visszahívás1 ()
}
// Végezzen explicit hibakezelést közvetlenül a hívás után.
func example3 () hiba {
    err: = hívás1 ()
    ha hibás! = nulla {
        visszatérési hiba
    }
    visszatérés nulla
}

A fenti megközelítések mindkettőnek megfelelőek. Ugyanazt érik el, ami; Ha valakinek hozzá kell adnia valamit a call1 () után, akkor gondoskodnia kell a hibakezelésről.

Ez minden mára

Kísérje figyelemmel a Go Best Practices-ról szóló következő cikket. Menj erős :).

func main () {
    err: = readArticle ("Go Best Practices - Hibakezelés")
    ha hibás! = nulla {
        ping ( "@ sebdah")
    }
}