Saya telah banyak berurusan dengan Lua dalam beberapa bulan terakhir, dan saya sangat menyukai sebagian besar fitur tetapi saya masih kehilangan sesuatu di antara mereka:
- Kenapa tidak ada
continue
? - Penanganan apa yang ada untuk itu?
loops
lua
language-design
Dant
sumber
sumber
goto
pernyataan yang dapat digunakan untuk mengimplementasikan melanjutkan. Lihat jawabannya di bawah.Jawaban:
Dalam Lua 5.2 solusi terbaik adalah menggunakan goto:
Ini didukung di LuaJIT sejak versi 2.0.1
sumber
continue
. Thegoto
pengganti tidak terlihat sangat bagus dan membutuhkan lebih banyak garis. Juga, bukankah itu akan menimbulkan masalah jika Anda memiliki lebih dari satu loop melakukan ini dalam satu fungsi, keduanya dengan::continue::
? Membuat nama per loop tidak terdengar seperti hal yang layak untuk dilakukan.Cara bahasa mengelola ruang lingkup leksikal menciptakan masalah dengan menyertakan keduanya
goto
dancontinue
. Sebagai contoh,Deklarasi
local a
di dalam loop body menutupi variabel luar bernamaa
, dan cakupan lokal itu meluas di seluruh kondisiuntil
pernyataan sehingga kondisi sedang menguji yang paling dalama
.Jika
continue
ada, itu harus dibatasi secara semantik hanya valid setelah semua variabel yang digunakan dalam kondisi tersebut masuk ke dalam ruang lingkup. Ini adalah kondisi yang sulit untuk didokumentasikan kepada pengguna dan ditegakkan dalam kompiler. Berbagai proposal seputar masalah ini telah dibahas, termasuk jawaban sederhana penolakancontinue
denganrepeat ... until
gaya loop. Sejauh ini, tidak ada yang memiliki kasus penggunaan yang cukup menarik untuk memasukkan mereka ke dalam bahasa.Pekerjaan sekitar umumnya untuk membalikkan kondisi yang akan menyebabkan a
continue
dieksekusi, dan mengumpulkan sisa tubuh loop di bawah kondisi itu. Jadi, loop berikutdapat ditulis
Ini cukup jelas, dan biasanya bukan beban kecuali Anda memiliki serangkaian pemusnahan rumit yang mengontrol operasi loop.
sumber
until...
.goto
ke dalam Lua 5.2. Secara alami,goto
memiliki masalah yang sama. Mereka akhirnya memutuskan bahwa apa pun biaya runtime dan / atau pembuatan kode untuk melindunginya tidak sepadan dengan manfaat memiliki fleksibelgoto
yang dapat digunakan untuk meniru keduanyacontinue
dan multi-levelbreak
. Anda harus mencari arsip daftar Lua untuk utas yang relevan untuk mendapatkan detailnya. Karena mereka memang memperkenalkangoto
, itu jelas tidak dapat diatasi.local
adalah arahan hanya kompiler - tidak peduli apa pun runtime insructions berada di antaralocal
dan penggunaan variabel - Anda tidak perlu mengubah apa pun di kompiler untuk mempertahankan perilaku pelingkupan yang sama. Ya, ini mungkin tidak begitu jelas dan memerlukan beberapa dokumentasi tambahan, tetapi, untuk mengulangi lagi, diperlukan perubahan NOL dalam kompiler.repeat do break end until true
contoh dalam jawaban saya sudah menghasilkan bytecode yang sama persis bahwa compiler akan melanjutkan, satu-satunya perbedaan adalah bahwa dengancontinue
Anda tidak perlu sintaks tambahan yang jelek untuk menggunakannya.do{int i=0;}while (i == 0);
gagal, atau dalam C ++:do int i=0;while (i==0);
juga gagal ("tidak dideklarasikan dalam lingkup ini"). Terlambat untuk mengubahnya sekarang di Lua, sayangnya.Anda dapat membungkus lingkaran tubuh di tambahan
repeat until true
dan kemudian gunakando break end
di dalam untuk efek melanjutkan. Secara alami, Anda perlu mengatur flag tambahan jika Anda juga bermaksud untuk benar-benarbreak
keluar dari loop.Ini akan berulang 5 kali, mencetak 1, 2, dan 3 setiap kali.
Konstruksi ini bahkan diterjemahkan menjadi opcode literal
JMP
dalam bytecode Lua!sumber
luac
output pada SO! Selamat menikmati :):Langsung dari desainer Lua sendiri :
sumber
continue
ke dalam Lua, maaf."Bagian pertama dijawab di FAQ sebagai dibunuh keluar runcing.
Adapun solusinya, Anda bisa membungkus tubuh loop dalam suatu fungsi dan
return
awal dari itu, misalnyaAtau jika Anda ingin keduanya
break
dancontinue
fungsionalitas, mintalah fungsi lokal melakukan tes, missumber
collectgarbage("count")
bahkan setelah 100 percobaan sederhana Anda dan kemudian kami akan berbicara. Optimalisasi "prematur" seperti itu menyelamatkan satu proyek highload dari reboot setiap menit minggu lalu.Saya belum pernah menggunakan Lua sebelumnya, tetapi saya mencari di Google dan menghasilkan ini:
http://www.luafaq.org/
Periksa pertanyaan 1.26 .
sumber
Kita dapat mencapainya seperti di bawah ini, ia akan melewati angka genap
O / P:
sumber
Kami mengalami skenario ini berkali-kali dan kami hanya menggunakan bendera untuk mensimulasikan melanjutkan. Kami mencoba untuk menghindari penggunaan pernyataan goto juga.
Contoh: Kode ini bermaksud untuk mencetak pernyataan dari i = 1 ke i = 10 kecuali i = 3. Selain itu ia juga mencetak "loop start", loop end "," if start ", dan" if end "untuk mensimulasikan pernyataan bersarang lainnya yang ada dalam kode Anda.
dicapai dengan melampirkan semua pernyataan yang tersisa sampai ruang lingkup akhir loop dengan bendera tes.
Saya tidak mengatakan bahwa ini adalah pendekatan terbaik tetapi itu bekerja dengan baik bagi kami.
sumber
Lua adalah bahasa scripting ringan yang ingin mengecil mungkin. Misalnya, banyak operasi unary seperti kenaikan sebelum / sesudah tidak tersedia
Alih-alih melanjutkan, Anda bisa menggunakan goto like
sumber
Sekali lagi dengan pembalik, Anda cukup menggunakan kode berikut:
sumber
Mengapa tidak ada yang melanjutkan?
Karena itu tidak perlu¹. Ada beberapa situasi di mana seorang dev akan membutuhkannya.
A) Ketika Anda memiliki loop yang sangat sederhana, katakanlah 1 atau 2-liner, maka Anda bisa membalikkan kondisi loop dan masih banyak yang bisa dibaca.
B) Ketika Anda menulis kode prosedural sederhana (alias. Bagaimana kami menulis kode pada abad terakhir), Anda juga harus menerapkan pemrograman terstruktur (alias. Bagaimana kami menulis kode yang lebih baik pada abad terakhir)
C) Jika Anda menulis kode berorientasi objek, badan loop Anda harus terdiri dari tidak lebih dari satu atau dua pemanggilan metode kecuali dapat dinyatakan dalam satu atau dua-liner (dalam hal ini, lihat A)
D) Jika Anda menulis kode fungsional, cukup kembalikan panggilan ekor untuk iterasi berikutnya.
Satu-satunya kasus ketika Anda ingin menggunakan
continue
kata kunci adalah jika Anda ingin kode Lua seperti itu python, padahal tidak .²Penanganan apa yang ada untuk itu?
Kecuali A) berlaku, dalam hal ini tidak perlu ada solusi, Anda harus melakukan pemrograman Terstruktur, Berorientasi Objek atau Fungsional. Itulah paradigma yang dibangun Lua, jadi Anda akan berjuang melawan bahasa jika Anda berusaha keras untuk menghindari pola mereka. Their
Beberapa klarifikasi:
¹ Lua adalah bahasa yang sangat minimalis. Itu mencoba untuk memiliki fitur sesedikit mungkin, dan
continue
pernyataan bukanlah fitur penting dalam arti itu.Saya pikir filosofi minimalis ini ditangkap dengan baik oleh Roberto Ierusalimschy dalam wawancara tahun 2019 ini :
² Tampaknya ada sejumlah besar programmer yang datang ke Lua dari bahasa lain karena program apa pun yang mereka coba skrip untuk menggunakannya, dan banyak dari mereka sepertinya tidak ingin menulis apa pun selain bahasa mereka sendiri. pilihan, yang mengarah ke banyak pertanyaan seperti "Mengapa Lua tidak memiliki fitur X?"
Matz menggambarkan situasi yang sama dengan Ruby dalam sebuah wawancara baru - baru ini :
³ Ada beberapa cara untuk meretas jalan Anda di sekitar ini; beberapa pengguna telah menyarankan untuk menggunakan
goto
, yang merupakan aproximation cukup baik dalam kebanyakan kasus, tetapi menjadi sangat jelek dengan sangat cepat dan benar-benar rusak dengan loop bersarang. Menggunakangoto
s juga menempatkan Anda dalam bahaya memiliki salinan SICP yang dilemparkan kepada Anda setiap kali Anda menunjukkan kode Anda kepada orang lain.sumber
continue
mungkin fitur yang nyaman, tetapi itu tidak membuatnya perlu . Banyak orang menggunakan Lua baik-baik saja tanpa itu, jadi benar-benar tidak ada kasus untuk itu selain fitur rapi yang tidak penting untuk bahasa pemrograman apa pun.