Pergi Amalan Terbaik - Pengendalian Ralat

Ini adalah artikel pertama dalam satu siri pengajaran yang saya pelajari selama beberapa tahun saya telah bekerja dengan Go dalam pengeluaran. Kami menjalankan banyak perkhidmatan Go dalam pengeluaran di Saltside Technologies (psst, saya mempekerjakan beberapa jawatan di Bangalore untuk Saltside) dan saya juga menjalankan perniagaan sendiri di mana Go adalah bahagian penting.

Kami akan meliputi pelbagai subjek, besar dan kecil.

Subjek pertama yang saya ingin sampaikan dalam siri ini adalah pengendalian ralat. Ini sering menyebabkan kekeliruan dan kegelisahan untuk pemaju Go baharu.

Beberapa latar belakang - Antara muka ralat

Hanya jadi kami berada di halaman yang sama. Seperti yang anda mungkin tahu ralat dalam Go hanyalah apa-apa yang melaksanakan antara muka ralat. Inilah yang kelihatan seperti definisi antara muka:

jenis antara muka ralat {
    Ralat () rentetan
}

Maka apa-apa yang melaksanakan kaedah Ralat () rentetan boleh digunakan sebagai ralat.

Memeriksa ralat

Menggunakan ralat ralat dan pemeriksaan jenis

Apabila saya mula menulis Pergi, saya sering melakukan perbandingan rentetan mesej ralat untuk melihat apa jenis ralat (ya, memalukan untuk memikirkan tetapi kadang-kadang anda perlu melihat kembali untuk maju).

Pendekatan yang lebih baik adalah menggunakan jenis ralat. Oleh itu, anda boleh (tentu saja) membuat struct yang melaksanakan antara muka ralat dan kemudian lakukan perbandingan jenis dalam pernyataan suis.

Inilah contoh pelaksanaan ralat.

taipkan ErrZeroDivision struct {
    rentetan mesej
}
func NewErrZeroDivision (string mesej) * ErrZeroDivision {
    pulangan & ErrZeroDivision {
        mesej: mesej,
    }
}
func (e * ErrZeroDivision) Ralat () string {
    kembali e.message
}

Sekarang ralat ini boleh digunakan seperti ini.

func main () {
    hasil, keliru: = membahagikan (1.0, 0.0)
    jika salah! = nil {
        menukar kesilapan (jenis) {
        kes * ErrZeroDivision:
            fmt.Println (err.Error ())
        lalai:
            fmt.Println ("Apa yang baru saja terjadi?")
        }
    }
    fmt.Println (hasil)
}
func divide (a, b float64) (float64, error) {
    jika b == 0.0 {
        kembali 0.0, NewErrZeroDivision ("Tidak dapat membahagikan dengan sifar")
    }
    kembali a / b, tiada
}

Berikut adalah pautan Go Play untuk contoh penuh. Perhatikan pola tukar ganti (jenis), yang memungkinkan untuk memeriksa jenis ralat yang berbeza daripada yang lain (seperti perbandingan rentetan atau sesuatu yang serupa).

Menggunakan pakej ralat dan perbandingan langsung

Pendekatan di atas boleh digunakan secara alternatif menggunakan pakej ralat. Pendekatan ini adalah disyorkan untuk pemeriksaan ralat dalam pakej di mana anda memerlukan perwakilan ralat yang cepat.

var errNotFound = errors.New ("Item tidak dijumpai")
func main () {
    err: = getItem (123) // Ini akan membuang errNotFound
    jika salah! = nil {
        menukar suis {
        kes salah laku:
            log.Println ("Item yang diminta tidak dijumpai")
        lalai:
            log.Println ("Ralat tidak diketahui berlaku")
        }
    }
}

Pendekatan ini kurang bagus apabila anda memerlukan objek ralat yang lebih rumit dengan contohnya. kod ralat dan lain-lain. Dalam kes ini, anda perlu membuat jenis anda sendiri yang melaksanakan antara muka ralat.

Pengendalian ralat serta-merta

Kadang-kadang saya mencari kod seperti di bawah (tetapi biasanya dengan lebih banyak fluff sekitar ..):

func example1 () error {
    err: = call1 ()
    kembali salah
}

Titik di sini adalah bahawa kesalahan itu tidak ditangani dengan serta-merta. Ini adalah pendekatan rapuh kerana seseorang boleh memasukkan kod antara kesilapan: = call1 () dan kesalahan pengembalian, yang akan memecahkan niat, kerana itu mungkin mengingatkan ralat pertama. Dua pendekatan alternatif:

// Runtuhkan pulangan dan ralat.
func example2 () error {
    kembali call1 ()
}
/ / Menangani kesilapan yang jelas selepas panggilan.
func example3 () error {
    err: = call1 ()
    jika salah! = nil {
        kembali salah
    }
    kembali nil
}

Kedua-dua pendekatan di atas adalah baik dengan saya. Mereka mencapai perkara yang sama, iaitu; jika seseorang perlu menambah sesuatu selepas call1 () mereka perlu menjaga pengendalian ralat.

Itu sahaja untuk hari ini

Tunggu untuk artikel seterusnya mengenai Go Best Practices. Pergi kuat :).

func main () {
    err: = readArticle ("Go Best Practices - handling error")
    jika salah! = nil {
        ping ("@ sebdah")
    }
}