Apakah praktik yang buruk untuk menggunakan pernyataan if tanpa kurung kurawal? [Tutup]

130

Saya telah melihat kode seperti ini:

if(statement)
    do this;
else
    do this;

Namun, saya pikir ini lebih mudah dibaca:

if(statement){
    do this;
}else{
    do this;
}

Karena kedua metode ini bekerja, apakah ini hanya masalah preferensi yang digunakan atau akankah satu cara direkomendasikan daripada yang lain?

jerebear
sumber
Menurut pendapat saya itu buruk, karena Anda mulai mengandalkan lekukan spasi putih yang hampir tidak pernah sepenuhnya konsisten. Ini menggagalkan pemikiran pembaca ketika mereka harus khawatir tentang hal-hal seperti itu.
Sridhar Sarnobat

Jawaban:

212

Masalah dengan versi pertama adalah bahwa jika Anda kembali dan menambahkan pernyataan kedua ke klausa jika atau yang lain tanpa ingat untuk menambahkan kurung kurawal, kode Anda akan pecah dengan cara yang tak terduga dan lucu.

Dari segi pemeliharaan, selalu lebih pintar menggunakan bentuk kedua.

EDIT: Ned menunjukkan hal ini dalam komentar, tapi saya pikir juga perlu menghubungkannya ke sini. Ini bukan hanya omong kosong hipotetis menara gading: https://www.imperialviolet.org/2014/02/22/applebug.html

clee
sumber
17
Dan Anda harus selalu kode untuk pemeliharaan. Lagi pula, saya cukup yakin kompiler tidak peduli bentuk mana yang Anda gunakan. Rekan kerja Anda, bagaimanapun, mungkin tidak sopan jika Anda memperkenalkan bug karena kesalahan kurung kurawal yang konyol.
Esteban Araya
12
Atau Anda dapat menggunakan bahasa yang tidak menggunakan tanda kurung untuk blok kode ...
Tor Valamo
10
@ lins314159 - Tidak, maksud saya seperti python. Karena saya chauvinistik dalam hal ini.
Tor Valamo
17
Kesalahan pembuktian lebih lanjut dapat (dan memang) terjadi: imperialviolet.org/2014/02/22/applebug.html
Ned
8
Mengklaim bahwa bug SSL adalah argumen yang mendukung kawat gigi adalah tidak jujur. Bukannya seolah-olah pengembang berniat menulis if (…) { goto L; goto L; }tetapi melupakan kawat gigi. Adalah murni kebetulan bahwa `` jika (...) {goto L; goto L; } `kebetulan bukan bug keamanan, karena bug itu masih bug (hanya saja bukan bug dengan konsekuensi keamanan). Pada contoh lain, berbagai hal bisa berjalan berlawanan arah dan kode tanpa gelang bisa secara tidak sengaja aman. Pada contoh ketiga, kode tanpa gelang akan bebas bug dan pengembang akan memperkenalkan kesalahan ketik sambil menambahkan kawat gigi.
Pascal Cuoq
112

Satu masalah dengan meninggalkan blok pernyataan adalah ambiguitas lain. Itu adalah bahasa yang terinspirasi C mengabaikan lekukan dan karenanya tidak memiliki cara untuk memisahkan ini:

if(one)
    if(two)
        foo();
    else
        bar();

Dari ini:

if(one)
    if(two)
        foo();
else
    bar();
doynax
sumber
8
Ini adalah masalah yang jauh lebih serius daripada yang disebutkan di jawaban atas (menambahkan pernyataan kedua).
3
memang, jawaban ini benar-benar membawa saya dari membaca jawaban-jawaban ini dengan sinis menjadi sedikit khawatir saya mungkin benar-benar membuat kesalahan ini.
omikes
2
Jika ada orang yang bertanya-tanya seperti saya di mana C benar-benar menafsirkannya, tes yang saya lakukan dengan GCC mengartikan kode ini dengan cara pertama. tpcg.io/NIYeqx
horta
2
"ambiguitas" adalah istilah yang salah. Tidak ada ambiguitas sama sekali dalam bagaimana parser akan melihat ini: elsemengikat dengan rakus ke terdekat, terdalam if. Masalah muncul ketika C atau bahasa yang sama sedang dikodekan oleh orang-orang yang tidak mengetahui hal ini, tidak memikirkannya, atau belum memiliki cukup kopi - jadi mereka menulis kode yang menurut mereka akan melakukan satu hal, tetapi spec bahasa mengatakan parser harus melakukan sesuatu yang lain, yang mungkin sangat berbeda. Dan ya, itu argumen kuat lain yang mendukung selalu memasukkan kawat gigi bahkan jika tata bahasa menandai mereka secara teoritis 'tidak perlu'.
underscore_d
35

Pola umum saya adalah bahwa jika cocok pada satu baris, saya akan melakukan:

if(true) do_something();

Jika ada klausa lain, atau jika kode yang ingin saya jalankan truepanjangnya signifikan, perkuat semua:

if(true) {
    do_something_and_pass_arguments_to_it(argument1, argument2, argument3);
}

if(false) {
    do_something();
} else {
    do_something_else();
}

Pada akhirnya, masalah ini adalah masalah gaya dan keterbacaan subyektif. Akan tetapi, dunia pemrograman secara umum terbagi menjadi dua pihak (untuk bahasa yang menggunakan kurung kurawal): baik menggunakannya sepanjang waktu tanpa terkecuali, atau menggunakannya sepanjang waktu dengan pengecualian. Saya bagian dari kelompok yang terakhir.

Matchu
sumber
4
Meskipun, semudah menulis if(true){ do_something(); }, mengapa mengambil kesempatan untuk memiliki programmer lain memperkenalkan bug serius di jalan (pencarian Apple "gagal goto" total kode ssl sekrup).
Craig
9
Kurung dalam jumlah berapa pun tidak akan membebaskan pengelola menggunakan otaknya. Saya mendukung gagasan "tidak ada tanda kurung jika cocok dalam satu baris" karena, bagi saya, jika itu hanya versi ternary jika operator di mana orang tidak perlu melakukan apa pun di bagian "sesudah:" ternary. Dan mengapa ada orang yang memperkenalkan kurung ke ternary jika ?
Michal M
Saya tidak setuju sama sekali bahwa pada akhirnya itu adalah subjektif, juga tidak hanya mempengaruhi gaya dan keterbacaan. Sebagai seseorang yang membuang waktu untuk men-debug masalah yang ternyata disebabkan oleh pembatas blok yang hilang (dan tidak memperhatikan ketidakhadiran mereka), karena saya harus menggunakan gaya pengkodean yang menghilangkannya ketika 'tidak perlu' - dan yang telah membaca banyak tentang bug yang mengerikan sangat mungkin disebabkan oleh gaya pengkodean seperti itu - saya pikir ini adalah masalah yang sangat objektif dan praktis. Tentu, dengan pembatas mandat gaya, kita masih bisa melupakannya, tapi tentu saja - setidaknya - memori otot membuat kita jauh lebih kecil kemungkinannya.
underscore_d
10

Saya menggunakan pemformat kode IDE yang saya gunakan. Itu mungkin berbeda, tetapi bisa diatur di Preferensi / Opsi.

Saya suka yang ini:

if (statement)
{
    // comment to denote in words the case
    do this;
    // keep this block simple, if more than 10-15 lines needed, I add a function for it
}
else
{
    do this;
}
Pentium10
sumber
5
Ini menjadi masalah gaya yang sepenuhnya subyektif, saya pribadi tidak suka redundansi dari garis brace saja. Tapi hey.
Matchu
14
Saya mendukung gaya ini. Kebanyakan orang membaca kode dari kiri ke kanan dan itu semacam membuat mata kita berlabuh ke tepi kiri layar. Ini membantu untuk secara visual memisahkan dan mengekstrak kode ke blok langkah logis.
mloskot
6
Saya selalu lebih suka gaya ini. Jauh lebih mudah untuk menemukan kurung tutup yang sesuai. Jadi butuh banyak ruang? Gunakan font yang lebih kecil.
timday
4
Saya selalu merasa lebih mudah untuk "memindai" melalui kode ketika kawat gigi berada di jalur yang terpisah. Itu berlaku untuk semuanya; kelas, metode, pernyataan if dan while, dan sebagainya. Tidak pernah suka memiliki penjepit pertama pada baris yang sama ...
Svish
2
Ruang kosong itu murah, terutama bila Anda memiliki IDE yang mampu melipat kode.
Moo
10

"Aturan" yang saya ikuti adalah ini:

Jika pernyataan "jika" sedang diuji untuk melakukan sesuatu (fungsi panggilan IE, konfigurasikan variabel, dll.), Gunakan kawat gigi.

if($test)
{
    doSomething();
}

Ini karena saya merasa Anda perlu memperjelas fungsi apa yang dipanggil dan ke mana aliran program, dalam kondisi apa. Membuat programmer memahami dengan tepat fungsi apa yang dipanggil dan variabel apa yang ditetapkan dalam kondisi ini penting untuk membantu mereka memahami apa yang sedang dilakukan oleh program Anda.

Jika pernyataan "jika" sedang menguji untuk berhenti melakukan sesuatu (kontrol aliran IE dalam satu loop atau fungsi), gunakan satu baris.

if($test) continue;
if($test) break;
if($test) return;

Dalam hal ini, yang penting bagi programmer adalah menemukan dengan cepat apa kasus luar biasa di mana Anda tidak ingin kode dijalankan, dan itu semua tercakup dalam $ test, bukan di blok eksekusi.

Marcus Harrison
sumber
8

Memasang kawat gigi sejak saat pertama akan membantu mencegah Anda dari harus men-debug ini:

if (statement)
     do this;
else
     do this;
     do that;
Matt Bishop
sumber
1
Itu tampaknya menjadi alasan yang diterima, tetapi (untuk berperan sebagai advokat iblis di sini) bukankah satu aturan penyorotan sintaks tambahan juga akan menyelesaikan masalah ini, sambil menyimpan satu baris?
Ken
2
Jadi akan ada IDE yang mengoreksi lekukan ketika Anda menekan ;:)
Sam Harwell
6

Gunakan tanda kurung untuk semua pernyataan bahkan pernyataan sederhana. Atau, tulis ulang pernyataan sederhana jika menggunakan operator ternary:

if (someFlag) {
 someVar= 'someVal1';
} else {
 someVar= 'someVal2';
}

Terlihat jauh lebih baik seperti ini:

someVar= someFlag ? 'someVal1' : 'someVal2';

Tetapi hanya gunakan operator ternary jika Anda benar-benar yakin tidak ada lagi yang perlu dimasukkan dalam blok if / else!

leepower
sumber
2

Dari pengalaman saya satu-satunya (sangat) sedikit keuntungan dari bentuk pertama adalah keterbacaan kode, bentuk kedua menambahkan "noise".

Tetapi dengan IDE modern dan autogenerasi kode (atau pelengkapan otomatis) saya sangat menyarankan untuk menggunakan formulir kedua, Anda tidak akan menghabiskan waktu ekstra mengetik kurung kurawal dan Anda akan menghindari beberapa bug yang paling sering.

Ada cukup banyak bug yang memakan energi, orang tidak perlu membuka pintu untuk buang-buang waktu.

Salah satu aturan paling penting untuk diingat ketika menulis kode adalah konsistensi. Setiap baris kode harus ditulis dengan cara yang sama, tidak peduli siapa yang menulisnya. Menjadi keras mencegah bug dari "terjadi";)

Ini sama dengan penamaan secara jelas & eksplisit variabel Anda, metode, file atau dengan indentasi dengan benar ...

Ketika murid-murid saya menerima fakta ini, mereka berhenti berjuang melawan kode sumber mereka sendiri dan mereka mulai melihat pengkodean sebagai kegiatan yang benar-benar menarik, merangsang dan kreatif. Mereka menantang pikiran mereka, bukan saraf mereka!

thomas.g
sumber
2

Ini masalah pilihan. Saya pribadi menggunakan kedua gaya, jika saya cukup yakin bahwa saya tidak perlu menambahkan pernyataan lagi, saya menggunakan gaya pertama, tetapi jika itu mungkin, saya menggunakan yang kedua. Karena Anda tidak dapat menambahkan lagi pernyataan ke gaya pertama, saya telah mendengar beberapa orang merekomendasikan untuk tidak menggunakannya. Namun, metode kedua tidak menimbulkan baris kode tambahan dan jika Anda (atau proyek Anda) menggunakan gaya pengkodean semacam ini, metode pertama sangat disukai untuk pernyataan sederhana jika:

if(statement)
{
    do this;
}
else
{
    do this;
}

Namun, saya pikir solusi terbaik untuk masalah ini adalah dengan Python. Dengan struktur blok berbasis spasi, Anda tidak memiliki dua metode berbeda untuk membuat pernyataan if: Anda hanya punya satu:

if statement:
    do this
else:
    do this

Meskipun memiliki "masalah" yang sama sekali tidak dapat Anda gunakan dengan kawat gigi, Anda mendapatkan keuntungan bahwa tidak ada lagi garis yang menjadi gaya pertama dan memiliki kekuatan untuk menambahkan lebih banyak pernyataan.

Hibah Paul
sumber
Saya sendiri berpikir bagaimana cara Python menangani pernyataan if-else sangat jelek, tapi sekali lagi, saya bukan programmer Python (belum)
helpermethod
1

Saya selalu mencoba untuk membuat kode standar saya dan terlihat sedekat mungkin. Ini memudahkan orang lain untuk membacanya ketika mereka bertugas memperbaharuinya. Jika Anda melakukan contoh pertama Anda dan menambahkan baris di tengah itu akan gagal.

Tidak akan bekerja:

jika (pernyataan) melakukan ini; dan ini; lain lakukan ini;

Joe
sumber
1

Secara pribadi saya menggunakan gaya pertama hanya membuang pengecualian atau kembali dari metode sebelum waktunya. Seperti pemeriksaan argumen di awal suatu fungsi, karena dalam kasus-kasus ini, saya jarang memiliki lebih dari satu hal untuk dilakukan, dan tidak pernah ada yang lain.

Contoh:

if (argument == null)
    throw new ArgumentNullException("argument");

if (argument < 0)
    return false;

Kalau tidak, saya menggunakan gaya kedua.

Nate Heinrich
sumber
1

Preferensi pribadi saya menggunakan campuran spasi dan kurung seperti ini:

if( statement ) {

    // let's do this

} else {

    // well that sucks

}

Saya pikir ini terlihat bersih dan membuat kode saya sangat mudah dibaca dan yang paling penting - debug.

Simon
sumber
0

Saya setuju dengan sebagian besar jawaban dalam kenyataan bahwa lebih baik untuk eksplisit dalam kode Anda dan menggunakan kawat gigi. Secara pribadi saya akan mengadopsi seperangkat standar pengkodean dan memastikan bahwa semua orang di tim tahu mereka dan sesuai. Di mana saya bekerja, kami menggunakan standar pengkodean yang diterbitkan oleh IDesign.net untuk proyek .NET.

Kane
sumber
0

Saya lebih suka memasang kurung kurawal. Tetapi kadang-kadang, operator ternary membantu.

Dari pada :

int x = 0;
if (condition) {
    x = 30;
} else {
    x = 10;
}

Satu hanya harus dilakukan: int x = condition ? 30 : 20;

Juga bayangkan sebuah kasus:

if (condition)
    x = 30;
else if (condition1)
    x = 10;
else if (condition2)
    x = 20;

Akan jauh lebih baik jika Anda memasukkan kurung kurawal.

fastcodejava
sumber