Penggunaan fungsi GOTOS pada PHP

Penggunaan fungsi GOTOS pada PHP


gotohampir secara universal putus asa. Apakah menggunakan pernyataan ini bermanfaat?






Jawaban:


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

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 menempatkan 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 bisa 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 gotodigunakan sebagai sarana untuk keluar dari sudut satu kode ke diri sendiri, dan umumnya merupakan gejala kode yang bisa dire-refored.







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. Pikirkan mereka sebagai goto yang dibatasi - dan pembatasanlah yang membuatnya bermanfaat. Pernyataan break diimplementasikan sebagai lompatan ke ujung loop tertutup, tetapi lebih baik dianggap beroperasi pada loop secara keseluruhan.

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

Tidak ada kasus di mana pernyataan goto mutlak diperlukan (ada teorema untuk efek itu), tetapi ada kasus di mana itu bisa menjadi solusi yang paling buruk. Kasing tersebut bervariasi dari satu bahasa ke bahasa lain, 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 tersebut 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.







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

Java telah berusaha untuk "memecahkan" masalah ini dengan menolak gotosepenuhnya. Namun, Java memungkinkan Anda menggunakan returndi dalam finallyblok dan dengan demikian menyebabkan pengecualian tertelan secara tidak sengaja. Masalah yang sama masih ada: kompiler tidak melakukan tugasnya. Menghapus gotodari bahasa belum memperbaikinya.

Dalam C #, gotoseaman break, continue, try/catch/finallydan return. Itu tidak membiarkan Anda menggunakan variabel yang tidak diinisialisasi, itu tidak membiarkan Anda melompat keluar dari blok akhirnya, dll. Kompiler akan mengeluh. Ini karena itu memecahkan masalah nyata , yang seperti saya katakan aliran kontrol tidak masuk akal. gototidak secara ajaib membatalkan analisis penugasan tertentu dan pengecekan wajar lainnya.



Iya nih. Ketika loop Anda bersarang dalam beberapa level, gotoadalah satu - satunya cara untuk melepaskan loop dalam secara elegan. 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, gotolebih baik.

Tentu saja, breakpernyataan berlabel Java melakukan hal yang sama, tetapi tanpa memungkinkan Anda untuk melompat ke titik sembarang dalam kode, yang menyelesaikan masalah dengan rapi tanpa membiarkan hal-hal yang membuat gotokejahatan.







Keputusasaan yang paling besar datang dari semacam "agama" yang telah diciptakan oleh Dewa Djikstra yang memaksa pada 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 gotopernyataan bahasa modern, yang keberadaannya semata-mata karena mendukung penciptaan struktur kode selain dari bahasa yang disediakan.

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

Anda dapat merujuk jawaban ini untuk mengetahui 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.

Tapi masalahnya bukan for. Ini aku.

Hal suka break, continue, throw, bool needed=true; while(needed) {...}, dll mencatat lebih dari masquerade goto untuk melarikan diri jauh dari pedang dari fanatik Djikstrarian, bahwa -50 tahun setelah penemuan laguages- modern yang masih ingin tawanan 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 gototidak perlu berurusan dengan GOTOpernyataan yang Djikstra tuntut.




Goto aneh di sini atau di sana, selama itu 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.



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

GOTO seperti itu tampaknya 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 jalur kontrol aliran di sini, tidak berbahaya.






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 ampuh (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 (misalnya, loop, pernyataan switch, dll.)


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.


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





gotomungkin berguna saat memindahkan kode assembler lawas ke C. Pada contoh pertama, konversi instruksi-demi-instruksi ke C, menggunakan gotosebagai pengganti untuk branchinstruksi assembler , dapat memungkinkan porting yang sangat cepat.


Saya berpendapat tidak. Mereka harus selalu diganti dengan alat yang lebih spesifik untuk masalah goto sedang digunakan untuk menyelesaikan (kecuali itu tidak tersedia dalam bahasa Anda). Sebagai contoh, break statemen dan pengecualian memecahkan masalah yang sebelumnya diselesaikan dengan kebohongan loop melarikan diri dan penanganan kesalahan.