Geriausia praktika - klaidų tvarkymas

Tai yra pirmas straipsnis iš pamokų, kurias išmokau per porą metų, kai dirbau su „Go“ gaminant. „Saltside Technologies“ gamina daugybę „Go“ paslaugų (psst. Aš įdarbinu keletą vietų Bangalore „Saltside“) ir aš taip pat palaikau savo verslą, kur „Go“ yra neatsiejama dalis.

Mes apimsime platų temų spektrą - didelius ir mažus.

Pirmasis dalykas, kurį norėjau aprėpti šioje serijoje, yra klaidų tvarkymas. Tai dažnai sukelia painiavą ir susierzinimą naujiems „Go“ kūrėjams.

Kai fonas - klaidos sąsaja

Tiesiog mes esame tame pačiame puslapyje. Kaip galbūt žinote, kad „Go“ klaida yra tiesiog viskas, kas įgyvendina klaidos sąsają. Kaip atrodo sąsajos apibrėžimas:

tipo klaidos sąsaja {
    Klaida () eilutė
}

Taigi kaip klaidą gali būti naudojamas bet kuris klaidos () eilutės metodas.

Tikrinimas, ar nėra klaidų

Klaidų struktūrų naudojimas ir tipo tikrinimas

Kai pradėjau rašyti „Go“, aš dažnai darydavau klaidų pranešimų palyginimus, norėdama pamatyti klaidos tipą (taip, gėdingai galvoti, bet kartais reikia žiūrėti atgal, kad galėtum eiti į priekį).

Geriau naudoti klaidų tipus. Taigi, jūs galite (žinoma) sukurti struktūrą, įgyvendinančią klaidos sąsają, ir tada palyginti tipą jungiklio teiginyje.

Čia pateiktas klaidų diegimo pavyzdys.

tipo „ErrZeroDivision“ konstrukcija {
    pranešimo eilutė
}
func NewErrZeroDivision (pranešimo eilutė) * ErrZeroDivision {
    grįžti & ErrZeroDivision {
        pranešimas: pranešimas,
    }
}
func (e * ErrZeroDivision) Klaida () eilutė {
    grąžinti el.pratimą
}

Dabar ši klaida gali būti naudojama taip.

func main () {
    rezultatas, klaid: = padalyti (1,0, 0,0)
    jei klaidinga! = nulis {
        jungiklio klaida (tipas) {
        atvejis * „ErrZeroDivision“:
            fmt.Println (klaid. klaidos ())
        numatytas:
            fmt.Println („Kas nutiko *?“)
        }
    }
    fmt.Println (rezultatas)
}
funkcijų padalijimas (a, b float64) (float64, klaida) {
    jei b == 0,0 {
        grąža 0.0, „NewErrZeroDivision“ („Negalima padalyti iš nulio“)
    }
    grįžti a / b, nulis
}

Čia yra viso pavyzdžio nuoroda „Pradėti žaisti“. Atkreipkite dėmesį į jungiklio klaidos (tipo) modelį, kuris leidžia patikrinti, ar nėra skirtingų klaidų, o ne kažko kito (pvz., Eilutės palyginimas ar kažkas panašaus).

Klaidų paketo naudojimas ir tiesioginis palyginimas

Aukščiau pateiktą metodą galima pakeisti naudojant klaidų paketą. Šis metodas yra rekomenduojamas atliekant klaidų tikrinimą pakete, kur jums reikia greitai parodyti klaidas.

var errNotFound = klaidos.Naujas („Prekės nerasta“)
func main () {
    err: = getItem (123) // Tai išmes errNotFound
    jei klaidinga! = nulis {
        perjungti klaidą {
        case errNotFound:
            log.Println („Prašoma prekė nerasta“)
        numatytas:
            log.Println („Įvyko nežinoma klaida“)
        }
    }
}

Šis požiūris nėra toks geras, kai reikia sudėtingesnių klaidų objektų, pvz. klaidų kodai ir tt Tokiu atveju turėtumėte sukurti savo tipą, kuris įgyvendina klaidos sąsają.

Greitas klaidų tvarkymas

Kartais aš susiduriu su tokiu kodu kaip žemiau (bet dažniausiai su daugiau pūkų ..):

„func example1“ () klaida {
    klaida: = skambinti1 ()
    grąžinti klaidą
}

Esmė ta, kad klaida nėra pašalinama iš karto. Tai yra trapus požiūris, nes kažkas gali įterpti kodą tarp err: = call1 () ir grąžinimo klaidos, o tai sugadintų ketinimą, nes tai gali užtemdyti pirmąją klaidą. Du alternatyvūs požiūriai:

// Sutraukite grąžą ir klaidą.
„func example2“ () klaida {
    atgalinis skambutis1 ()
}
// Atlikite aiškų klaidų tvarkymą iškart po skambučio.
func example3 () klaida {
    klaida: = skambinti1 ()
    jei klaidinga! = nulis {
        grąžinti klaidą
    }
    grąžinti nulį
}

Abu minėti požiūriai man tinka. Jie pasiekia tą patį dalyką, kuris yra; jei kas nors turi ką nors pridėti po skambučio1 (), jis turi pasirūpinti klaidų tvarkymu.

Tai viskas siandienai

Sekite naujus straipsnius apie „Geriausios praktikos pavyzdžius“. Eik stiprus :).

func main () {
    err: = readArticle („Geriausia praktika - klaidų tvarkymas“)
    jei klaidinga! = nulis {
        „ping“ („@ sebdah“)
    }
}