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.
"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:
mengontrol kode keluar dari program untuk tujuan scripting.
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.
"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:
os.Exit melewatkan eksekusi fungsi yang ditangguhkan.
Dengan os.Exit, Anda dapat menentukan kode keluar.
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:
fungsinya mengandung banyak cabang
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:
Gunakan panicketika sesuatu yang benar-benar terjadi, misalnya kesalahan logika pemrograman.
Gunakan os.Exitsaat Anda ingin segera keluar, dengan kode keluar yang ditentukan.
panic
digunakan 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 memesanpanic
untuk situasi yang sangat khusus.panic
adalah bawaan. Dianjurkan (tergantung pada keadaan) untuk menggunakan sesuatu sepertios.Exit
,log.Fatal
dll., 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.Jawaban:
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.Exit
danpanic
sangat berbeda.panic
digunakan saat program, atau bagiannya, mencapai status tidak dapat dipulihkan.os.Exit
digunakan 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 sebagaierror
gantinya), dan Anda hampir tidak perlu dios.Exit
luar beberapa kasus dalam pengujian dan untuk penghentian program yang cepat.sumber
exit
dalam kasus itu, saya hanya mengharapkan tumpukan besar pernyataan gagal.)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 menggunakanrecover
.Tetapi jika kita berbicara tentang kode keluar yang salah, katakanlah:
Gunakan
panic
jika 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:mengontrol kode keluar dari program untuk tujuan scripting.
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.
sumber
Perbedaan utamanya adalah:
os.Exit
melewatkan eksekusi fungsi yang ditangguhkan.os.Exit
, Anda dapat menentukan kode keluar.panic
mengakhiri sementaraos.Exit
tidak. (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, gunakanos.Exit
.)Jika fungsi non-void didefinisikan sedemikian rupa:
return
ataupanic
Maka Anda tidak dapat mengganti
panic
denganos.Exit
sebaliknya kompilator akan menolak untuk mengkompilasi program, mengatakan "pengembalian hilang pada akhir fungsi". (Go sangat bodoh di sini, bahkanlog.Panic
tidak menghentikan suatu fungsi.)Dalam kondisi lain:
panic
ketika sesuatu yang benar-benar terjadi, misalnya kesalahan logika pemrograman.os.Exit
saat Anda ingin segera keluar, dengan kode keluar yang ditentukan.sumber