Izmantojiet labāko praksi - kļūdu novēršana

Šis ir pirmais raksts nodarbību sērijā, ko esmu iemācījies pāris gadu laikā, kad esmu strādājis ar Go ražošanā. Uzņēmumā Saltside Technologies mēs piedāvājam lielu skaitu Go pakalpojumu ražošanas jomā (psst. Es pieņemu darbā vairākus amatus Bangalore par Saltside), un es vadu arī savu biznesu, kurā Go ir neatņemama sastāvdaļa.

Mēs apskatīsim plašu tēmu klāstu - gan lielus, gan mazus.

Pirmais temats, ko es gribēju aptvert šajā sērijā, ir kļūdu apstrāde. Tas bieži rada neskaidrības un īgnumu jaunajiem Go izstrādātājiem.

Daži foni - kļūdas saskarne

Mēs esam tajā pašā lapā. Kā jūs zināt, kļūda pakalpojumā Go ir vienkārši viss, kas ievieš kļūdas saskarni. Šādi izskatās interfeisa definīcija:

tipa kļūdas saskarne {
    Kļūda () virkne
}

Tātad kā kļūdu var izmantot jebko, kas īsteno virknes kļūdu () metodi.

Pārbaude, vai nav kļūdu

Kļūdu struktūru izmantošana un tipa pārbaude

Kad es sāku rakstīt Go, es bieži veica kļūdu ziņojumu salīdzinājumus, lai redzētu, kāds ir kļūdas tips (jā, mulsinoši domāt, bet dažreiz jums ir jāatskatās atpakaļ, lai turpinātu).

Labāka pieeja ir kļūdu veidu izmantošana. Tātad jūs varat (protams) izveidot struktūras, kas ievieš kļūdas saskarni, un pēc tam veikt tipa salīdzināšanu komutācijas paziņojumā.

Šis ir kļūdu ieviešanas piemērs.

tips ErrZeroDivision struct {
    ziņojuma virkne
}
func NewErrZeroDivision (ziņojuma virkne) * ErrZeroDivision {
    atgriešanās & ErrZeroDivision {
        ziņa: ziņa,
    }
}
func (e * ErrZeroDivision) Kļūda () virkne {
    atgriezt e-pastu
}

Tagad šo kļūdu var izmantot šādi.

func main () {
    rezultāts, kļūda: = dalīt (1,0, 0,0)
    ja kļūda! = nulle {
        slēdža kļūda (tips) {
        lieta * ErrZeroDivision:
            fmt.Println (kļūda.Error ())
        noklusējums:
            fmt.Println ("Kas tieši notika ar h *?")
        }
    }
    fmt.Println (rezultāts)
}
func dalījums (a, b float64) (float64, kļūda) {
    ja b == 0,0 {
        atgriešanās 0,0, NewErrZeroDivision ("Nevar dalīt ar nulli")
    }
    atgriezt a / b, nulle
}

Pilna piemēra saite ir Go Play. Ievērojiet slēdža kļūdas (veida) modeli, kas ļauj pārbaudīt dažādu kļūdu veidus, nevis kaut ko citu (piemēram, virkņu salīdzinājumu vai kaut ko līdzīgu).

Kļūdu paketes izmantošana un tiešs salīdzinājums

Iepriekš minēto pieeju var arī izmantot, izmantojot kļūdu paketi. Šī pieeja ir ieteicama kļūdu pārbaudē paketē, kur nepieciešama ātra kļūdu attēlošana.

var errNotFound = kļūdas.Jauns ("Vienums nav atrasts")
func main () {
    err: = getItem (123) // Tas radīs errNotFound
    ja kļūda! = nulle {
        slēdzis kļūda {
        lieta errNotFound:
            log.Println ("Pieprasītā prece nav atrasta")
        noklusējums:
            log.Println ("Radās nezināma kļūda")
        }
    }
}

Šī pieeja nav tik laba, ja nepieciešami sarežģītāki kļūdu objekti ar, piem. kļūdu kodi utt. Tādā gadījumā jums vajadzētu izveidot savu tipu, kas ievieš kļūdas saskarni.

Tūlītēja kļūdu novēršana

Dažreiz es sastopos ar kodu, piemēram, zemāk (bet parasti ar vairāk pūku ap ..):

func example1 () kļūda {
    kļūda: = izsaukums1 ()
    atgriešanās kļūda
}

Lieta ir tāda, ka kļūda netiek nekavējoties apstrādāta. Šī ir nestabila pieeja, jo kāds var ievietot kodu starp err: = call1 () un atgriešanās kļūdu, kas sagrautu nodomu, jo tas var aizēnot pirmo kļūdu. Divas alternatīvas pieejas:

// Sakļaut atgriešanos un kļūdu.
func example2 () kļūda {
    atgriešanās zvans1 ()
}
// Dariet skaidru kļūdu apstrādi tūlīt pēc zvana.
func example3 () kļūda {
    kļūda: = izsaukums1 ()
    ja kļūda! = nulle {
        atgriešanās kļūda
    }
    atgriešanās nulle
}

Abas iepriekš minētās pieejas man ir piemērotas. Viņi sasniedz to pašu, kas ir; ja kādam kaut kas jāpievieno pēc izsaukuma1 (), viņam jārūpējas par kļūdu apstrādi.

Tas viss šodien

Sekojiet līdzi nākamajam rakstam par Go Best Practice. Ej stipri :).

func main () {
    err: = readArticle ("Labākā prakse - kļūdu novēršana")
    ja kļūda! = nulle {
        ping ("@ sebdah")
    }
}