Saya menulis beberapa kode yang terlihat seperti ini:
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
break; // **HERE, I want to break out of the loop itself**
}
}
Apakah ada cara langsung untuk melakukan itu?
Saya tahu saya bisa menggunakan sebuah bendera, dan keluar dari perulangan dengan meletakkan jeda bersyarat tepat setelah saklar. Saya hanya ingin tahu apakah C ++ sudah memiliki beberapa konstruksi untuk ini.
goto
menarik dan, terkadang, satu-satunya jalan keluar yang bersih. Jika Anda cenderung mengatur kode Anda menjadi fungsi-fungsi kecil yang panjangnya hanya beberapa baris dan masing-masing melakukan satu hal, Anda tidak akan pernah mengalami masalah ini. (Kebetulan kode Anda juga akan lebih mudah dibaca.):)
Jawaban:
Premis
Kode berikut harus dianggap bentuk yang buruk, terlepas dari bahasa atau fungsi yang diinginkan:
Argumen Pendukung
Bentuk
while( true )
loopnya buruk karena:while(true)
untuk loop yang tidak terbatas, kita kehilangan kemampuan untuk berkomunikasi secara ringkas ketika loop sebenarnya tidak memiliki kondisi penghentian. (Bisa dibilang, ini sudah terjadi, jadi intinya diperdebatkan.)Alternatif untuk "Pergi ke"
Kode berikut adalah bentuk yang lebih baik:
Keuntungan
Tidak ada bendera. Tidak
goto
. Tanpa pengecualian. Mudah diubah. Mudah dibaca. Mudah diperbaiki. Selain itu kode:Poin kedua penting. Tanpa mengetahui cara kerja kode, jika seseorang meminta saya untuk membuat loop utama, biarkan utas (atau proses) lain memiliki waktu CPU, dua solusi muncul dalam pikiran:
Pilihan 1
Masukkan jeda dengan mudah:
Pilihan 2
Timpa eksekusi:
Kode ini lebih sederhana (sehingga lebih mudah dibaca) daripada loop dengan embedded
switch
. TheisValidState
Metode hanya harus menentukan apakah loop harus terus. Pekerja keras metode ini harus diabstraksikan ke dalamexecute
metode, yang memungkinkan subclass untuk menimpa perilaku default (tugas yang sulit menggunakanswitch
dan tertanamgoto
).Contoh Python
Bandingkan jawaban berikut (dengan pertanyaan Python) yang diposting di StackOverflow:
Melawan:
Di sini,
while True
menghasilkan kode yang menyesatkan dan terlalu kompleks.sumber
while(true)
semestinya berbahaya tampak aneh bagi saya. Ada loop yang memeriksa sebelum dieksekusi, ada yang memeriksa setelahnya, dan ada yang memeriksa di tengah. Karena yang terakhir tidak memiliki konstruksi sintaksis dalam C dan C ++, Anda harus menggunakanwhile(true)
ataufor(;;)
. Jika Anda menganggap ini salah, Anda belum cukup memikirkan jenis loop yang berbeda.while(true) {string line; std::getline(is,line); if(!is) break; lines.push_back(line);}
Tentu saja saya bisa mengubah ini menjadi loop prakondisi (menggunakanstd::getline
sebagai kondisi loop), tetapi ini memiliki kelemahan sendiri (line
harus menjadi variabel di luar lingkup loop). Dan jika saya melakukannya, saya harus bertanya: Mengapa kita memiliki tiga putaran? Kami selalu dapat mengubah semuanya menjadi loop yang telah ditentukan sebelumnya. Gunakan yang paling cocok. Jikawhile(true)
cocok, maka gunakanlah.Anda bisa menggunakan
goto
.sumber
goto
. OP dengan jelas menyebutkan tanpa menggunakan bendera . Bisakah Anda menyarankan cara yang lebih baik, mengingat keterbatasan OP? :)Solusi alternatifnya adalah dengan menggunakan kata kunci
continue
dalam kombinasi denganbreak
, yaitu:Gunakan
continue
pernyataan untuk menyelesaikan setiap label kasus di mana Anda ingin pengulangan melanjutkan dan gunakanbreak
pernyataan untuk menyelesaikan label kasus yang harus menghentikan pengulangan.Tentu saja solusi ini hanya berfungsi jika tidak ada kode tambahan untuk dieksekusi setelah pernyataan switch.
sumber
:(
:(
Jika tidak, implementasi yang sangat bersih.Cara yang rapi untuk melakukan ini adalah dengan memasukkan ini ke dalam sebuah fungsi:
Opsional (tapi 'praktik buruk'): seperti yang sudah disarankan, Anda bisa menggunakan goto, atau melempar pengecualian di dalam sakelar.
sumber
AFAIK tidak ada "istirahat ganda" atau konstruksi serupa di C ++. Yang paling dekat adalah a
goto
- yang, meskipun memiliki konotasi buruk untuk namanya, ada dalam bahasa karena suatu alasan - selama digunakan dengan hati-hati dan hemat, itu adalah opsi yang layak.sumber
Anda dapat meletakkan sakelar Anda ke fungsi terpisah seperti ini:
sumber
Bahkan jika Anda tidak suka goto, jangan gunakan pengecualian untuk keluar dari loop. Contoh berikut menunjukkan betapa jeleknya itu:
Saya akan menggunakan
goto
seperti dalam jawaban ini . Dalam hal inigoto
akan membuat kode lebih jelas daripada opsi lainnya. Saya berharap bahwa ini pertanyaan akan membantu.Tapi saya pikir menggunakan
goto
adalah satu-satunya pilihan di sini karena stringnyawhile(true)
. Anda harus mempertimbangkan refactoring loop Anda. Saya kira solusi berikut:Atau bahkan yang berikut ini:
sumber
goto
, jangan tidak menggunakan pengecualian untuk keluar loop:"?Tidak ada konstruksi C ++ untuk mendobrak loop dalam kasus ini.
Gunakan flag untuk menghentikan loop atau (jika sesuai) ekstrak kode Anda ke dalam fungsi dan gunakan
return
.sumber
Anda berpotensi menggunakan goto, tetapi saya lebih suka menyetel bendera yang menghentikan pengulangan. Kemudian keluar dari sakelar.
sumber
Mengapa tidak memperbaiki kondisi di while loop Anda, menyebabkan masalah hilang?
sumber
Tidak, C ++ tidak memiliki konstruksi untuk ini, mengingat kata kunci "break" sudah disediakan untuk keluar dari blok switch. Alternatifnya, do.. while () dengan flag exit sudah cukup.
sumber
Kupikir;
sumber
Cara termudah untuk melakukannya adalah dengan meletakkan IF sederhana sebelum Anda melakukan SWITCH, dan IF menguji kondisi Anda untuk keluar dari loop ......... sesederhana mungkin
sumber
Kata
break
kunci dalam C ++ hanya mengakhiri iterasi atauswitch
pernyataan yang paling bertingkat . Jadi, Anda tidak bisa keluar dariwhile (true)
loop langsung di dalamswitch
pernyataan; namun Anda dapat menggunakan kode berikut, yang menurut saya merupakan pola yang sangat baik untuk jenis masalah ini:Jika Anda perlu melakukan sesuatu saat
msg->state
samaDONE
(seperti menjalankan rutinitas pembersihan), letakkan kode tersebut segera setelahfor
pengulangan; yaitu jika saat ini Anda memiliki:Kemudian gunakan sebagai gantinya:
sumber
Sungguh mengherankan saya betapa sederhananya ini mengingat kedalaman penjelasan ... Inilah yang Anda butuhkan ...
LOL !! Betulkah! Hanya itu yang Anda butuhkan! Satu variabel ekstra!
sumber
sumber
Saya mendapat masalah yang sama dan diselesaikan dengan menggunakan bendera.
sumber
Jika saya mengingat sintaks C ++ dengan baik, Anda dapat menambahkan label ke
break
pernyataan, seperti untukgoto
. Jadi apa yang Anda inginkan akan mudah ditulis:sumber
sumber