Selama yang saya ingat, saya telah menghindari penggunaan fall-through pernyataan switch. Sebenarnya, saya tidak dapat mengingatnya pernah memasuki kesadaran saya sebagai cara yang mungkin untuk melakukan sesuatu karena sudah dibor di kepala saya sejak awal bahwa itu tidak lebih dari bug dalam pernyataan switch. Namun, hari ini saya menemukan beberapa kode yang menggunakannya dengan desain, yang membuat saya langsung bertanya-tanya apa yang dipikirkan semua orang di komunitas tentang fall-through pernyataan switch.
Apakah itu sesuatu yang seharusnya tidak diizinkan secara eksplisit oleh bahasa pemrograman (seperti C #, meskipun ia menyediakan solusi) atau apakah itu fitur dari bahasa apa pun yang cukup kuat untuk ditinggalkan di tangan programmer?
Sunting: Saya tidak cukup spesifik untuk apa yang saya maksud dengan fall-through. Saya sering menggunakan tipe ini:
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something
break;
case 2:
case 3:
case 4:
// Do something
break;
}
Namun, saya khawatir tentang hal seperti ini.
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something, but fall through to the other cases
// after doing it.
case 2:
case 3:
case 4:
// Do something else.
break;
}
Dengan cara ini setiap kali case adalah 0, 1 itu akan melakukan semua yang ada di pernyataan switch. Saya telah melihat ini dengan sengaja dan saya tidak tahu apakah saya setuju bahwa pernyataan sakelar harus digunakan dengan cara ini. Saya rasa contoh kode pertama ini sangat berguna dan aman. Yang kedua sepertinya berbahaya.
sumber
Jawaban:
Itu mungkin tergantung pada apa yang Anda anggap salah. Saya setuju dengan hal semacam ini:
Tetapi jika Anda memiliki label kasus diikuti dengan kode yang jatuh ke label kasus lain, saya akan selalu menganggap itu jahat. Mungkin memindahkan kode umum ke suatu fungsi dan memanggil dari kedua tempat akan menjadi ide yang lebih baik.
Dan perlu diketahui bahwa saya menggunakan definisi FAQ C ++ tentang "jahat"
sumber
Itu pedang bermata dua. Terkadang sangat berguna, tetapi seringkali berbahaya.
Kapan itu enak? Bila Anda ingin 10 kasus semua diproses dengan cara yang sama ...
Satu aturan yang saya suka adalah jika Anda pernah melakukan sesuatu yang mewah di mana Anda mengecualikan jeda, Anda memerlukan komentar yang jelas / * FALLTHROUGH * / untuk menunjukkan bahwa itu adalah niat Anda.
sumber
if(condition > 1 && condition <10) {condition = 1}; switch(...
menyelamatkan kasus (agar terlihat jelas) dan semua orang dapat melihat bahwa Anda benar-benar ingin kasus tersebut memicu tindakan yang sama.Pernahkah Anda mendengar tentang perangkat Duff ? Ini adalah contoh yang bagus dalam menggunakan fallthrough sakelar.
Ini adalah fitur yang dapat digunakan dan dapat disalahgunakan, seperti hampir semua fitur bahasa.
sumber
Fall-through adalah hal yang berguna, tergantung pada apa yang Anda lakukan. Pertimbangkan cara yang rapi dan mudah dipahami ini untuk mengatur opsi:
Bayangkan melakukan ini dengan if / else. Ini akan menjadi berantakan.
sumber
Ini bisa sangat berguna beberapa kali, tetapi secara umum, tidak ada kesalahan dalam perilaku yang diinginkan. Pergantian harus diizinkan, tetapi tidak implisit.
Contoh, untuk memperbarui versi lama beberapa data:
sumber
Saya ingin sintaks yang berbeda untuk fallback di sakelar, sesuatu seperti, errr ..
Catatan: Ini sudah bisa dilakukan dengan enum, jika Anda mendeklarasikan semua kasus di enum Anda menggunakan flag, bukan? Kedengarannya juga tidak terlalu buruk; kasus bisa (harus?) sangat baik menjadi bagian dari enum Anda sudah.
Mungkin ini akan menjadi kasus yang bagus (tidak ada permainan kata-kata) untuk antarmuka yang lancar menggunakan metode ekstensi? Sesuatu seperti, errr ...
Meskipun itu mungkin bahkan kurang terbaca: P
sumber
Seperti apa pun: jika digunakan dengan hati-hati, ini bisa menjadi alat yang elegan.
Namun, menurut saya kekurangannya lebih dari sekadar membenarkan untuk tidak menggunakannya, dan akhirnya tidak mengizinkannya lagi (C #). Diantara masalahnya adalah:
Penggunaan yang baik dari switch / case fall-through:
Baaaaad penggunaan switch / case fall-through:
Ini dapat ditulis ulang menggunakan if / else konstruksi tanpa kerugian sama sekali menurut saya.
Kata terakhir saya: jauhi label case fall-through seperti pada contoh buruk , kecuali Anda mempertahankan kode warisan di mana gaya ini digunakan dan dipahami dengan baik.
sumber
Itu sangat kuat dan berbahaya. Masalah terbesar dengan fall-through adalah bahwa hal itu tidak eksplisit. Misalnya, jika Anda menemukan kode yang sering diedit yang memiliki sakelar dengan fall-through, bagaimana Anda tahu itu disengaja dan bukan bug?
Di mana pun saya menggunakannya, saya memastikan komentar itu benar:
sumber
Menggunakan fall-through seperti pada contoh pertama Anda jelas OK, dan saya tidak akan menganggapnya sebagai fall-through yang nyata.
Contoh kedua berbahaya dan (jika tidak dikomentari secara ekstensif) tidak jelas. Saya mengajar siswa saya untuk tidak menggunakan konstruksi seperti itu kecuali mereka menganggap itu sepadan dengan upaya untuk mencurahkan blok komentar padanya, yang menjelaskan bahwa ini adalah kesalahan yang disengaja, dan mengapa solusi ini lebih baik daripada alternatifnya. Ini mencegah penggunaan yang ceroboh, tetapi tetap membuatnya diperbolehkan dalam kasus di mana digunakan untuk keuntungan.
Ini kurang lebih sama dengan apa yang kami lakukan dalam proyek luar angkasa ketika seseorang ingin melanggar standar pengkodean: mereka harus mengajukan dispensasi (dan saya dipanggil untuk memberi nasihat tentang keputusan itu).
sumber
Saya tidak suka
switch
pernyataan saya gagal - terlalu rawan kesalahan dan sulit dibaca. Satu-satunya pengecualian adalah ketika beberapacase
pernyataan semuanya melakukan hal yang persis sama.Jika ada beberapa kode umum yang ingin digunakan oleh beberapa cabang pernyataan switch, saya mengekstraknya menjadi fungsi umum terpisah yang dapat dipanggil di cabang mana pun.
sumber
Dalam beberapa kasus, menggunakan fall-through adalah tindakan kemalasan di pihak programmer - mereka bisa menggunakan rangkaian || pernyataan, misalnya, tetapi menggunakan serangkaian kasus sakelar 'penampung-semua'.
Karena itu, saya merasa mereka sangat membantu ketika saya mengetahuinya pada akhirnya saya akan tetap memerlukan opsi (misalnya dalam respons menu), tetapi belum menerapkan semua pilihan. Demikian juga, jika Anda melakukan fall-through untuk 'a' dan 'A', saya merasa jauh lebih bersih menggunakan sakelar fall-through daripada pernyataan gabungan if.
Ini mungkin masalah gaya dan bagaimana pemrogram berpikir, tetapi saya umumnya tidak suka menghapus komponen bahasa atas nama 'keamanan' - itulah sebabnya saya cenderung ke arah C dan varian / turunannya lebih dari, katakanlah, Jawa. Saya suka bisa bermain-main dengan petunjuk dan sejenisnya, bahkan ketika saya tidak punya "alasan" untuk itu.
sumber
Fall-through harus digunakan hanya jika digunakan sebagai tabel lompat ke dalam blok kode. Jika ada bagian dari kode dengan jeda tanpa syarat sebelum lebih banyak kasus, semua grup kasus harus diakhiri dengan cara itu.
Yang lainnya adalah "jahat".
sumber