Saya baru saja mulai menggunakan Go. Kode saya mulai memiliki banyak ini:
if err != nil {
//handle err
}
atau ini
if err := rows.Scan(&some_column); err != nil {
//handle err
}
Apakah ada beberapa idiom / strategi / praktik terbaik untuk memeriksa dan menangani kesalahan di Go?
EDIT untuk mengklarifikasi: Saya tidak bersungut-sungut atau menyarankan agar tim Go membuat sesuatu yang lebih baik. Saya bertanya apakah saya melakukannya dengan benar atau apakah saya melewatkan beberapa teknik yang dibuat komunitas. Terima kasih semuanya.
Jawaban:
Kode Anda idiomatis dan menurut saya ini adalah praktik terbaik yang tersedia. Beberapa pasti tidak setuju, tapi saya berpendapat bahwa ini adalah gaya yang terlihat di seluruh perpustakaan standar di Golang . Dengan kata lain, penulis Go menulis penanganan kesalahan dengan cara ini.
sumber
Enam bulan setelah pertanyaan ini diajukan, Rob Pike menulis entri blog berjudul Errors are Values .
Di sana dia berpendapat bahwa Anda tidak perlu memprogram dengan cara yang disajikan oleh OP, dan menyebutkan beberapa tempat di perpustakaan standar di mana mereka menggunakan pola yang berbeda.
Bacaan yang bagus.
sumber
Saya setuju dengan jawaban jnml bahwa keduanya adalah kode idiomatik, dan menambahkan yang berikut:
Contoh pertama Anda:
lebih idiomatis saat berurusan dengan lebih dari satu nilai pengembalian. sebagai contoh:
Contoh kedua Anda adalah singkatan yang bagus ketika hanya berurusan dengan
err
nilai. Ini berlaku jika fungsi hanya mengembalikanerror
, atau jika Anda sengaja mengabaikan nilai yang dikembalikan selainerror
. Sebagai contoh, ini terkadang digunakan dengan fungsiReader
danWriter
yang mengembalikanint
jumlah byte tertulis (terkadang informasi yang tidak perlu) danerror
:Bentuk kedua disebut menggunakan pernyataan inisialisasi if .
Jadi, berkenaan dengan praktik terbaik, sejauh yang saya tahu (kecuali untuk menggunakan "kesalahan" paket untuk membuat kesalahan baru saat Anda membutuhkannya) Anda telah membahas hampir semua yang perlu Anda ketahui tentang kesalahan di Go!
EDIT: Jika Anda merasa benar - benar tidak dapat hidup tanpa pengecualian, Anda dapat menirunya dengan
defer
,panic
&recover
.sumber
Saya membuat perpustakaan untuk menangani kesalahan yang efisien dan menyalurkan melalui antrian fungsi Go.
Anda dapat menemukannya di sini: https://github.com/go-on/queue
Ini memiliki varian sintaksis kompak dan verbose. Berikut adalah contoh sintaks pendek:
Perlu diketahui bahwa ada sedikit beban kinerja, karena ini memanfaatkan refleksi.
Juga ini bukan kode go idiomatik, jadi Anda akan ingin menggunakannya dalam proyek Anda sendiri, atau jika tim Anda setuju untuk menggunakannya.
sumber
Sebuah "strategi" untuk menangani kesalahan di golang dan dalam bahasa lain adalah terus-menerus menyebarkan kesalahan ke tumpukan panggilan sampai Anda cukup tinggi dalam tumpukan panggilan untuk menangani kesalahan itu. Jika Anda mencoba menangani kesalahan itu terlalu dini, kemungkinan besar Anda akan mengulangi kode. Jika Anda menanganinya terlambat, maka Anda akan merusak sesuatu dalam kode Anda. Golang membuat proses ini sangat mudah karena membuatnya sangat jelas apakah Anda menangani kesalahan di lokasi tertentu atau memperbanyaknya.
Jika Anda akan mengabaikan kesalahan, _ sederhana akan mengungkapkan fakta ini dengan sangat jelas. Jika Anda menanganinya, maka kasus kesalahan mana yang Anda tangani sudah jelas karena Anda akan memeriksanya di pernyataan if.
Seperti kata orang di atas, error sebenarnya hanyalah nilai normal. Ini memperlakukannya seperti itu.
sumber
Dewa Go telah menerbitkan sebuah "rancangan rancangan" untuk penanganan kesalahan di Go 2. Ini bertujuan untuk mengubah idiom kesalahan:
Gambaran Umum dan Desain
Mereka menginginkan umpan balik dari pengguna!
Umpan balik wiki
Secara singkat, ini terlihat seperti:
PEMBARUAN: Desain draf telah menerima banyak kritik, jadi saya menyusun Persyaratan untuk Dipertimbangkan untuk Penanganan Kesalahan Go 2 dengan menu kemungkinan untuk solusi akhirnya.
sumber
Sebagian besar di industri, mengikuti aturan standar yang disebutkan dalam dokumentasi Golang Penanganan Error dan Go . Dan itu juga membantu pembuatan dokumen untuk proyek.
sumber
Di bawah ini adalah pendapat saya untuk mengurangi penanganan kesalahan pada Go, contoh untuk saat mendapatkan parameter HTTP URL:
(Pola desain berasal dari https://blog.golang.org/errors-are-values )
memanggilnya untuk beberapa parameter yang mungkin adalah seperti di bawah ini:
Ini bukan peluru perak, sisi negatifnya adalah jika Anda memiliki banyak kesalahan, Anda hanya bisa mendapatkan kesalahan terakhir.
Tetapi dalam hal ini relatif berulang dan berisiko rendah, oleh karena itu saya hanya bisa mendapatkan kemungkinan kesalahan terakhir.
sumber
Anda bisa membersihkan kode penanganan kesalahan Anda untuk kesalahan serupa (karena kesalahan adalah nilai yang harus Anda perhatikan di sini) dan menulis fungsi yang Anda panggil dengan kesalahan yang diteruskan untuk menangani kesalahan. Anda tidak perlu menulis "if err! = Nil {}" setiap saat. Sekali lagi, ini hanya akan menghasilkan pembersihan kode, tetapi saya tidak berpikir itu adalah cara idiomatik dalam melakukan sesuatu.
Sekali lagi, hanya karena Anda bisa tidak berarti Anda harus melakukannya .
sumber
goerr memungkinkan untuk menangani kesalahan dengan fungsi
sumber
Jika Anda ingin kontrol kesalahan yang tepat, ini mungkin bukan solusinya, tetapi bagi saya, sebagian besar waktu, kesalahan apa pun adalah penghenti acara.
Jadi, saya menggunakan fungsi sebagai gantinya.
sumber
stderr
daripadastdout
, jadi gunakan sajalog.Fatal(err)
ataulog.Fatalln("some message:", err)
. Karena hampir tidak ada selain yangmain
harus membuat keputusan seperti itu untuk mengakhiri seluruh program (yaitu mengembalikan kesalahan dari fungsi / metode, jangan batalkan) dalam kasus yang jarang terjadi, inilah yang ingin Anda lakukan itu lebih bersih dan lebih baik untuk melakukannya secara eksplisit (mis.if err := someFunc(); err != nil { log.Fatal(err) }
) daripada melalui fungsi "pembantu" yang tidak jelas tentang apa yang dilakukannya (nama "Err" tidak baik, tidak ada indikasi bahwa ia dapat menghentikan program).