Kapan menggunakan os.Exit () dan panic ()?

96

Bisakah seseorang menjelaskan perbedaan utama antara os.Exit()dan panic()dan bagaimana penggunaannya dalam praktik di Go?

Timur Fayzrakhmanov
sumber
11
Hanya komentar yang mudah-mudahan akan membantu di masa depan membaca kode Go: Dalam banyak contoh kode, panicdigunakan untuk keluar dari kesalahan, murni karena fakta bahwa itu mudah dimengerti, dan menghilangkan pengimporan paket lain. Ini tidak berarti itu bagus, atau latihan idiomatis! . Ini hanya perangkat penghemat ruang untuk kode contoh. IRL memesan panicuntuk situasi yang sangat khusus.
Intermernet
2
Hm..baik) terutama singkatan "IRL" - ini baru bagi saya :) Bisakah Anda menjelaskan bagaimana kepanikan menghilangkan pengimporan paket?
Timur Fayzrakhmanov
5
panicadalah bawaan. Dianjurkan (tergantung pada keadaan) untuk menggunakan sesuatu seperti os.Exit, log.Fataldll., Yang akan mengembalikan kode kesalahan ke OS (selalu disarankan jika memungkinkan). Ini semua melibatkan pengimporan paket, dan dengan demikian kode contoh "mengacaukan". Kode contoh hanya boleh diambil untuk mendemonstrasikan solusi untuk masalah tertentu. Mungkin ada masalah lain dengan kode, yang membuat kode lebih kompleks jika didemonstrasikan dengan benar, dan karena itu mengurangi penjelasan jawaban yang diberikan. YMMV.
Intermernet
1
Ok, mengerti!) Terima kasih banyak) Saya melihat ada singkatan lain untuk kosakata saya :)
Timur Fayzrakhmanov
2
NP, dengan senang hati membantu, dan untuk meningkatkan leksikon
akronimis

Jawaban:

86

Pertama-tama, setiap kali Anda memiliki pertanyaan "bagaimana penggunaannya dalam praktik", cara yang baik untuk memulai adalah mencari kode sumber Go (atau basis kode Go yang cukup besar, sungguh), dan dokumen paket untuk jawabannya.

Sekarang, os.Exitdan panicsangat berbeda. panicdigunakan saat program, atau bagiannya, mencapai status tidak dapat dipulihkan.

Saat panicdipanggil, termasuk secara implisit untuk error run-time seperti mengindeks slice di luar batas atau menggagalkan pernyataan tipe, ia segera menghentikan eksekusi fungsi saat ini dan mulai melepas tumpukan goroutine, menjalankan fungsi yang ditangguhkan di sepanjang jalan. Jika pelepasan itu mencapai puncak tumpukan goroutine, program akan mati.

os.Exitdigunakan saat Anda perlu membatalkan program segera, tanpa kemungkinan pemulihan atau menjalankan pernyataan pembersihan yang ditangguhkan, dan juga mengembalikan kode kesalahan (yang dapat digunakan program lain untuk melaporkan apa yang terjadi). Ini berguna dalam pengujian, ketika Anda sudah tahu bahwa setelah pengujian yang satu ini gagal, pengujian yang lain juga akan gagal, jadi Anda sebaiknya keluar sekarang. Ini juga dapat digunakan ketika program Anda telah melakukan semua yang perlu dilakukan, dan sekarang hanya perlu keluar, yaitu setelah mencetak pesan bantuan.

Sebagian besar waktu Anda tidak akan menggunakan panic(Anda harus mengembalikan sebagai errorgantinya), dan Anda hampir tidak perlu di os.Exitluar beberapa kasus dalam pengujian dan untuk penghentian program yang cepat.

Ainar-G
sumber
9
"Ini berguna dalam tes, ketika Anda sudah tahu bahwa setelah tes yang satu ini gagal, yang lain juga akan gagal…" Ini berbau tes anti-pola tes dependen. Dalam rangkaian pengujian yang ditulis dengan baik, setiap pengujian bersifat independen; hasil dari setiap tes tidak boleh menentukan hasil dari tes lain.
gotgenes
1
@gotgenes Belum tentu. Jika saya memiliki tes bahwa fungsi tertentu mengembalikan struct non-nil, dan tes itu gagal, maka saya dapat mengharapkan bahwa semua tes yang memeriksa nilai-nilai struct akan gagal juga. Ini kodenya yang bergantung, bukan tesnya. (Yang mengatakan, saya tidak akan menggunakan exitdalam kasus itu, saya hanya mengharapkan tumpukan besar pernyataan gagal.)
David Moles
84

Pertama-tama, os.Exit()dapat digunakan untuk keluar dari program secara normal tanpa kesalahan, dan tidak panik, jadi itulah salah satu perbedaan utama. Hal lainnya adalah kepanikan di suatu tempat dapat ditangkap dan diabaikan atau dicatat menggunakan recover.

Tetapi jika kita berbicara tentang kode keluar yang salah, katakanlah:

Gunakan panicjika ada yang tidak beres, mungkin kesalahan programmer yang seharusnya sudah diketahui sebelum pergi ke produksi. Inilah mengapa ini mencetak tumpukan.

Gunakan os.Exit(errorCode)atau sesuatu seperti itu jika Anda ingin:

  1. mengontrol kode keluar dari program untuk tujuan scripting.

  2. ingin keluar secara tertib pada kesalahan yang diharapkan (mis. kesalahan input pengguna).

Jadi pada dasarnya panik untuk Anda, kode keluar yang buruk untuk pengguna Anda.

Not_a_Golfer
sumber
Terima kasih sangat membantu!)
Timur Fayzrakhmanov
14
"Jadi pada dasarnya panik untuk Anda, kode keluar yang buruk untuk pengguna Anda." <- Tip luar biasa
psousa
1
Bisakah kita mengatakan bahwa panik () entah bagaimana terkait dengan panggilan assert () biasa di C? Yah .. Saya tahu saya selalu menghapus panggilan yang menegaskan sebelum mendorong ke produksi, saya hanya mengaktifkannya saat menguji fitur baru. Apa yang saya katakan adalah bahwa sebagian besar waktu saya menggunakan assert () untuk memverifikasi invarian yang menurut saya harus benar dalam kode saya. Apakah Anda melihat penggunaan yang sama untuk panic ()? :-)
yves Baumes
7

Perbedaan utamanya adalah:

  1. os.Exit melewatkan eksekusi fungsi yang ditangguhkan.
  2. Dengan os.Exit, Anda dapat menentukan kode keluar.
  3. panicmengakhiri sementara os.Exittidak. (Sepertinya jawaban lain tidak menyebutkan ini.)

Jika Anda perlu menjalankan fungsi deferred, Anda tidak punya pilihan selain panic. (Di sisi lain, jika Anda ingin melewatkan eksekusi fungsi yang ditangguhkan, gunakan os.Exit.)

Jika fungsi non-void didefinisikan sedemikian rupa:

  1. fungsinya mengandung banyak cabang
  2. semua cabang diakhiri dengan returnataupanic

Maka Anda tidak dapat mengganti panicdengan os.Exitsebaliknya kompilator akan menolak untuk mengkompilasi program, mengatakan "pengembalian hilang pada akhir fungsi". (Go sangat bodoh di sini, bahkan log.Panictidak menghentikan suatu fungsi.)

Dalam kondisi lain:

  1. Gunakan panicketika sesuatu yang benar-benar terjadi, misalnya kesalahan logika pemrograman.
  2. Gunakan os.Exitsaat Anda ingin segera keluar, dengan kode keluar yang ditentukan.
lemah
sumber