it-swarm-id.com

Apakah menggunakan goto bermanfaat?

goto hampir tidak dianjurkan secara universal. Apakah menggunakan pernyataan ini bermanfaat?

30
Casebash

Ini telah dibahas beberapa kali di Stack Overflow, dan Chris Gillum merangkum kemungkinan penggunaan goto :

Keluar dari suatu fungsi dengan bersih

Seringkali dalam suatu fungsi, Anda dapat mengalokasikan sumber daya dan harus keluar di banyak tempat. Pemrogram dapat menyederhanakan kode mereka dengan meletakkan kode pembersihan sumber daya di akhir fungsi semua "titik keluar" dari fungsi akan kebagian label pembersihan. Dengan cara ini, Anda tidak perlu menulis kode pembersihan di setiap "titik keluar" dari fungsi.

Keluar dari loop bersarang

Jika Anda berada di loop bersarang dan harus keluar dari semua loop, goto dapat membuat ini jauh lebih bersih dan lebih sederhana daripada pernyataan break dan jika-cek.

Peningkatan kinerja tingkat rendah

Ini hanya valid dalam kode perf-critical, tetapi pernyataan goto mengeksekusi sangat cepat dan dapat memberi Anda dorongan ketika bergerak melalui suatu fungsi. Namun ini adalah pedang bermata dua, karena kompiler biasanya tidak dapat mengoptimalkan kode yang berisi gotos.

Saya berpendapat, seperti banyak orang lain akan berpendapat, bahwa dalam semua kasus ini, penggunaan goto digunakan sebagai sarana untuk keluar dari sudut satu kode ke diri sendiri, dan umumnya merupakan gejala kode yang bisa di refactored.

51
user8

Konstruksi aliran kontrol level yang lebih tinggi cenderung sesuai dengan konsep dalam domain masalah. If/else adalah keputusan berdasarkan beberapa kondisi. Loop mengatakan untuk melakukan beberapa tindakan berulang kali. Bahkan pernyataan break mengatakan "kami melakukan ini berulang kali, tapi sekarang kami harus berhenti".

Pernyataan goto, di sisi lain, cenderung sesuai dengan konsep dalam program yang sedang berjalan, bukan dalam domain masalah. Dikatakan untuk melanjutkan eksekusi pada titik tertentu dalam program . Seseorang yang membaca kode harus menyimpulkan apa artinya sehubungan dengan domain masalah.

Tentu saja semua konstruksi tingkat yang lebih tinggi dapat didefinisikan dalam hal gotos dan cabang kondisional sederhana. Itu tidak berarti bahwa mereka hanya goto yang menyamar. Anggap saja sebagai dibatasi gotos - dan itu adalah batasan yang membuatnya berguna. Pernyataan break diimplementasikan sebagai lompatan ke ujung loop tertutup, tetapi lebih baik dianggap beroperasi pada loop secara keseluruhan.

Semua yang lain sama, kode yang strukturnya mencerminkan bahwa dari domain masalah cenderung lebih mudah dibaca dan dipelihara.

Tidak ada kasus di mana pernyataan goto benar-benar diperlukan (ada teorema untuk efek itu), tetapi ada kasus di mana itu bisa menjadi solusi paling buruk. Kasing tersebut bervariasi dari satu bahasa ke bahasa lainnya, tergantung pada tingkat konstruksi apa yang didukung oleh bahasa tersebut.

Di C, misalnya, saya percaya ada tiga skenario dasar di mana goto sesuai.

  1. Keluar dari loop bersarang. Ini tidak perlu jika bahasa tersebut memiliki pernyataan istirahat berlabel.
  2. Bailing keluar dari hamparan kode (biasanya badan fungsi) jika terjadi kesalahan atau peristiwa tak terduga lainnya. Ini tidak perlu jika bahasa memiliki pengecualian.
  3. Menerapkan mesin negara hingga eksplisit. Dalam kasus ini (dan, saya pikir, hanya dalam kasus ini) goto berhubungan langsung dengan konsep dalam domain masalah, transisi dari satu keadaan ke keadaan lain yang ditentukan, di mana keadaan saat ini diwakili oleh blok kode mana yang sedang dijalankan .

Di sisi lain, mesin negara hingga eksplisit juga dapat diimplementasikan dengan pernyataan switch di dalam loop. Ini memiliki keuntungan bahwa setiap negara mulai di tempat yang sama dalam kode, yang dapat berguna untuk debugging, misalnya.

Penggunaan utama goto dalam bahasa modern yang cukup (yang mendukung jika/else dan loop) adalah untuk mensimulasikan konstruksi aliran kontrol yang hilang dari bahasa.

46
Keith Thompson

Tentunya itu tergantung pada bahasa pemrogramannya. Alasan utama goto telah menjadi kontroversial adalah karena efek buruknya yang muncul ketika kompiler memungkinkan Anda menggunakannya terlalu bebas. Masalah dapat muncul, misalnya, jika memungkinkan Anda menggunakan goto sedemikian rupa sehingga Anda sekarang dapat mengakses variabel yang tidak diinisialisasi, atau lebih buruk, untuk melompat ke metode lain dan mengacaukan tumpukan panggilan. Seharusnya menjadi tanggung jawab kompiler untuk melarang aliran kontrol yang tidak masuk akal.

Java telah berusaha untuk "memecahkan" masalah ini dengan melarang goto seluruhnya. Namun, Java memungkinkan Anda menggunakan return di dalam blok finally dan dengan demikian menyebabkan pengecualian tertelan secara tidak sengaja. Masalah yang sama masih ada: kompilernya adalah tidak melakukan tugasnya. Menghapus goto dari bahasa belum memperbaikinya.

Dalam C #, goto seaman break, continue, try/catch/finally dan return. Itu tidak membiarkan Anda menggunakan variabel tidak diinisialisasi, itu tidak membiarkan Anda melompat keluar dari blok akhirnya, dll. Kompiler akan mengeluh. Ini karena ia memecahkan masalah nyata, yang seperti saya katakan aliran kontrol tidak masuk akal. goto tidak secara ajaib membatalkan analisis penetapan-tugas tertentu dan pemeriksaan kompiler yang masuk akal lainnya.

11
Timwi

Iya. Ketika loop Anda bersarang beberapa level, goto adalah hanya cara elegan keluar dari loop dalam. Opsi lainnya adalah mengatur bendera dan keluar dari setiap loop jika bendera itu memenuhi syarat. Ini benar-benar jelek, dan sangat rentan kesalahan. Dalam kasus ini, goto lebih baik.

Tentu saja, pernyataan break berlabel Java melakukan hal yang sama, tetapi tanpa memungkinkan Anda untuk melompat ke titik sembarang dalam kode, yang memecahkan masalah dengan rapi tanpa membiarkan hal-hal yang membuat goto jahat.

9
Chinmay Kanchi

Keputusasaan yang paling besar datang dari semacam "agama" yang telah diciptakan oleh Dewa Djikstra yang mendesak di awal tahun 60an tentang kekuatannya yang membabi buta untuk:

  • lompat ke mana saja ke dalam blok kode apa pun
    • fungsi tidak dijalankan dari awal
    • loop tidak dieksekusi dari awal
    • inisialisasi variabel yang dilewati
  • melompat menjauh dari blok kode apa pun tanpa pembersihan apa pun.

Ini tidak ada hubungannya dengan pernyataan goto dari bahasa modern, yang keberadaannya semata-mata karena mendukung penciptaan struktur kode selain bahasa yang disediakan.

Khususnya, titik utama pertama di atas diizinkan lagi dan yang kedua dibersihkan (jika Anda goto keluar dari blok, tumpukan dilepaskan dengan benar dan semua penghancur yang tepat dipanggil)

Anda dapat merujuk jawaban ini untuk memiliki gagasan tentang bagaimana bahkan kode yang tidak menggunakan goto dapat dibaca. Masalahnya bukan goto itu sendiri, tetapi penggunaannya yang buruk.

Saya dapat menulis seluruh program tanpa menggunakan if, hanya for. Tentu saja, itu tidak akan mudah dibaca, terlihat canggung dan tidak perlu rumit.

Tetapi masalahnya bukan for. Ini aku.

Hal-hal seperti break, continue, throw, bool needed=true; while(needed) {...}, dll. Mencatat lebih dari masquerade goto untuk melarikan diri dari pedang para fanatik Djikstrarian, bahwa -50 tahun setelah penemuan lagu-lagu modern- masih menginginkan para tahanan mereka. Mereka lupa apa yang dibicarakan Djikstra, mereka hanya ingat judul catatannya (GOTO dianggap berbahaya, dan itu bahkan bukan judulnya sendiri: itu diubah oleh editor) dan menyalahkan dan bash, bash dan menyalahkan setiap konstruksi yang memiliki 4 surat ditempatkan secara berurutan.

Ini tahun 2011: saatnya untuk memahami bahwa goto telah mencatat untuk berurusan dengan pernyataan GOTO yang ditekankan oleh Djikstra.

7

Goto aneh di sini atau di sana, selama itu bersifat lokal untuk suatu fungsi, jarang secara signifikan merusak keterbacaan. Seringkali manfaat dengan menarik perhatian pada fakta bahwa ada sesuatu yang tidak biasa terjadi dalam kode ini yang memerlukan penggunaan struktur kontrol yang agak tidak biasa.

Jika goto (lokal) secara signifikan merusak keterbacaan, maka itu biasanya merupakan tanda bahwa fungsi yang mengandung goto menjadi terlalu kompleks.

Goto terakhir yang saya masukkan ke dalam sepotong kode C adalah membangun sepasang loop yang saling terkait. Ini tidak sesuai dengan definisi normal penggunaan goto "dapat diterima", tetapi fungsi tersebut berakhir secara signifikan lebih kecil dan lebih jelas. Untuk menghindari kebotakan akan membutuhkan pelanggaran DRY yang sangat berantakan.

4
blucz

Saya pikir seluruh masalah ini adalah kasus menggonggong pohon yang salah.

GOTO seperti itu sepertinya tidak bermasalah bagi saya, tetapi itu lebih sering merupakan gejala dari dosa yang sebenarnya: kode spaghetti.

Jika GOTO menyebabkan persimpangan besar garis kontrol aliran maka itu buruk, titik. Jika tidak ada garis kontrol aliran, itu tidak berbahaya. Di zona abu-abu di antara kami memiliki hal-hal seperti bailout lingkaran, masih ada beberapa bahasa yang belum menambahkan konstruksi yang mencakup semua kasus abu-abu yang sah.

Satu-satunya kasus saya menemukan diri saya benar-benar menggunakannya dalam beberapa tahun adalah kasus loop di mana titik keputusan berada di tengah-tengah loop. Anda memiliki kode duplikat, bendera, atau GOTO. Saya menemukan solusi GOTO yang terbaik dari ketiganya. Tidak ada persimpangan garis kontrol aliran di sini, tidak berbahaya.

3
Loren Pechtel

Ya, goto dapat digunakan untuk memberi manfaat pada pengalaman pengembang: http://adamjonrichardson.com/2012/02/06/long-live-the-goto-statement/

Namun, seperti halnya alat yang kuat (pointer, multiple inheritance, dll.), Seseorang harus disiplin menggunakannya. Contoh yang disediakan dalam tautan menggunakan PHP, yang membatasi penggunaan konstruksi goto ke fungsi/metode yang sama dan menonaktifkan kemampuan untuk melompat ke blok kontrol baru (mis., Loop, pernyataan switch, dll.)

1
AdamJonR

Tergantung pada bahasanya. Ini masih banyak digunakan dalam pemrograman Cobol, misalnya. Saya juga bekerja pada perangkat Barionet 50, yang bahasa pemrograman firmware-nya adalah dialek BASIC awal yang tentu saja mengharuskan Anda untuk menggunakan Goto.

1
user16764

Saya akan mengatakan tidak. Jika Anda merasa perlu menggunakan GOTO, saya berani bertaruh bahwa ada kebutuhan untuk mendesain ulang kode.

0
Walter

goto mungkin berguna ketika porting kode assembler lawas ke C. Pada contoh pertama, konversi instruksi-oleh-instruksi ke C, menggunakan goto sebagai pengganti untuk assembler's branch instruksi, dapat memungkinkan porting sangat cepat.

0
Graham Borland