Mengapa Menggunakan! Boolean_variable Lebih dari boolean_variable == false

60

Komentar untuk pertanyaan ini: Memeriksa apakah suatu metode mengembalikan false: menugaskan hasil ke variabel sementara, atau menempatkan pemanggilan metode secara langsung dalam kondisi? mengatakan bahwa Anda harus menggunakannya !booleandaripada boolean == falsesaat menguji kondisi. Mengapa? Bagi saya boolean == falsejauh lebih alami dalam bahasa Inggris dan lebih eksplisit. Saya minta maaf jika ini hanya masalah gaya, tapi saya bertanya-tanya apakah ada alasan lain untuk preferensi ini !boolean?

ell
sumber
28
Lebih pendek untuk menulis.
Zenon
39
Ini seperti melakukan boolean == true: itu tidak masuk akal. Ekspresi di dalam ifpernyataan hanyalah: ekspresi. Jika sesuatu sudah mengevaluasi ekspresi boolean, mengapa Anda menambahkan cek untuk memaksanya mengevaluasi itu?
Maks.
10
@zzzzBov: Um, tidak. Bukan itu yang dilakukan oleh kebanyakan programmer (gaya C).
amara
9
@zzzzBov: Komentar Anda ambigu. Jika Anda maksudkan itu !boolean_variableadalah cara kebanyakan programmer C melakukannya, saya setuju.
Keith Thompson
29
Dan yang lebih penting, kenapa tidak ada yang mau menulis boolean != true?

Jawaban:

153

Ketika saya melihat garis seperti if (!lateForMeeting()), saya membaca itu sebagai "Jika tidak terlambat untuk bertemu" , yang cukup mudah untuk dipahami, sebagai kebalikan dari if (lateForMeeting() == false)yang saya baca sebagai "Jika fakta bahwa saya terlambat untuk bertemu adalah salah " .

Mereka identik dalam arti, tetapi yang pertama lebih dekat dengan bagaimana kalimat bahasa Inggris yang setara akan dibangun.

kba
sumber
27
+1 Dalam Python Anda benar-benar menulis if not late_for_meeting:)
phunehehe
42
Saya berpendapat bahwa jika "jika ___ salah" terdengar lebih alami daripada "jika bukan ___", maka nama ___ perlu ditingkatkan.
Mike DeSimone
12
Di Perl, Anda dapat menulisunless late_for_meeting
Henrik Ripa
4
@HenrikRipa: Sepertinya hampir semua yang bisa Anda ketik adalah kode legal di Perl. Apakah itu melakukan apa yang Anda inginkan atau tidak adalah pertanyaan lain;)
Adam Robinson
4
@ A-Cube Saya tidak akan memiliki metode seperti itu untuk memulai. Sebaliknya, saya akan memanggil metode done(). Negatif ganda itu buruk.
kba
97

Menulis == falsedan == trueberlebihan. Itu juga bisa dianggap ekstrem yang sewenang-wenang. Jika Anda mulai menulis

if (condition == false) { ... }

Lalu mengapa tidak

if ((condition == false) == true) { ... }

Atau mengapa tidak

if ((someExp == anotherExp) == true) { ... }

Moral dari cerita ini adalah bahwa jika itu conditionadalah ekspresi boolean, maka Anda tidak perlu menambahkan == false; untuk itulah operator !;)

Andres F.
sumber
Tidak memikirkan ini!
ell
51
== falseBUKAN berlebihan, hanya lebih bertele-tele daripada !. OTOH, == trueberlebihan.
dan04
4
@ dan04 Kamu benar. Namun, dalam arti saya bersungguh-sungguh, itu tetap merupakan ide yang buruk. Pertimbangkan (exp1 != exp2)vs ((exp1 == exp2) == false). Memang, ini adalah skenario yang dibuat-buat, tetapi tetap saja Anda harus hampir tidak pernah menulis perbandingan eksplisit untuk benar atau salah. Sama seperti Anda harus menggunakan operator !=, Anda juga harus menggunakannya !.
Andres F.
26
@ dan04: Ini berlebihan ketika bahasa sudah menawarkan !.
DeadMG
5
@ dan04: Setiap kali Anda menulis bool_expression == bool_literal, == ...itu mubazir. Apakah Anda menguji benar atau salah tidak relevan. Itu hanya perubahan dalam urutan blok konsekuensi / alternatif. Contoh-contoh Andres menggambarkan hal ini dengan sempurna. Sebagian besar kompiler modern akan mengoptimalkan redundansi, tetapi masih berlebihan.
Lèse majesté
70

Dalam bahasa C dan beberapa bahasa yang serupa, membandingkan ekspresi boolean untuk kesetaraan dengan falseatau truemerupakan kebiasaan berbahaya.

Dalam C, ekspresi skalar apa saja (angka atau penunjuk) dapat digunakan dalam konteks boolean, misalnya sebagai kondisi ifpernyataan. C aturan adalah bahwa if (cond)setara dengan if (cond != 0)- yaitu, nol adalah palsu, dan setiap nilai bukan nol benar. Jika condtipe pointer, 0diperlakukan sebagai konstanta pointer nol; if (ptr)berarti if (ptr != NULL).

Ini artinya

if (cond)

dan

if (cond == true)

tidak berarti hal yang sama . Yang pertama benar jika condtidak nol; yang kedua adalah benar hanya jika itu sama dengan true, yang di C (jika Anda punya #include <stdbool.h>) sederhana 1.

Misalnya, isdigit()fungsi yang dideklarasikan dalam <ctype.h>mengembalikan intnilai, 0jika argumennya adalah digit, bukan nol jika bukan. Dapat kembali 42untuk menunjukkan bahwa kondisinya benar. Membandingkan 42 == trueakan gagal.

Kebetulan 0satu-satunya nilai yang dianggap salah, jadi perbandingan kesetaraan dengan falseakan berhasil; if (!cond)dan if (cond == false)melakukan hal yang sama. Tetapi jika Anda akan mengambil keuntungan dari itu, Anda harus ingat bahwa membandingkan dengan falseitu ok, dan membandingkan dengan trueitu tidak. Lebih buruk lagi, membandingkan dengan trueakan bekerja sebagian besar waktu (misalnya, operator kesetaraan dan relasional selalu menghasilkan salah satu 0atau 1). Ini berarti bahwa setiap bug yang Anda perkenalkan dengan menggunakan ini masih sulit dilacak. (Jangan khawatir, mereka akan muncul segera setelah Anda demo kode ke klien penting.)

C ++ memiliki aturan yang sedikit berbeda; misalnya, booltipenya sedikit lebih terintegrasi ke dalam bahasa, dan if (cond)mengkonversi conduntuk mengetik bool. Tetapi efeknya (kebanyakan) sama.

Beberapa bahasa lain memiliki apa yang orang sebut boolean berperilaku lebih baik, sehingga cond == truedan cond == false(atau apa pun sintaks yang terjadi) aman. Meski begitu, setiap bahasa yang saya lihat memiliki notatau !operator; itu ada di sana, jadi Anda sebaiknya menggunakannya. Menggunakan cond == falsedaripada !condatau not condtidak, menurut saya, meningkatkan keterbacaan. (Memang benar bahwa !karakter bisa sulit dilihat sekilas; Saya kadang-kadang menambahkan spasi setelah !untuk menghindari ini.)

Dan seringkali Anda dapat menghindari masalah dan meningkatkan kejelasan dengan mengatur ulang kode sedikit. Misalnya, daripada:

if (!cond) {
    do_this();
}
else {
    do_that();
}

Anda mungkin menulis:

if (cond) {
     do_that();
}
else {
    do_this();
}

Itu tidak selalu lebih baik, tetapi tidak ada salahnya mencari peluang di tempat itu.

Ringkasan: Dalam C dan C ++, perbandingan kesetaraan dengan truedan falseberbahaya, terlalu bertele-tele, dan gaya yang buruk. Dalam banyak bahasa lain, perbandingan seperti itu mungkin tidak berbahaya, tetapi masih terlalu bertele-tele dan gaya yang buruk.

Keith Thompson
sumber
+1 untuk ini menjadi satu jawaban dengan penjelasan teknis berguna yang sebenarnya.
Mike Nakis
Saya masih berpikir seperti ini, terlepas dari bahasa pemrograman saya selalu menganggap itu == truetidak aman. Terasa lebih baik seperti itu.
Dervall
1
@Ervall: mengasumsikan sesuatu yang tidak terjadi juga tidak baik. Ada beberapa kasus sudut dalam bahasa tertentu di mana perbandingan kesetaraan boolean tidak hanya aman tetapi pada kenyataannya sesuai, misalnya dalam Haskell, yang memiliki sistem tipe bebas-cor yang kuat dengan inferensi tipe dua arah, orang mungkin menulis (==True) . funtuk memperjelas bahwa kami ingin -> Boolinstantiation dari fungsi kembali-polimorfik f. Itu lebih jelas daripada not . not . fdan kurang canggung daripada (f :: a -> Bool).
leftaroundabout
Juga, tentu saja tepat untuk melakukan hal-hal seperti pred(x)==pred(y)untuk fungsi bool-return pred. Alternatif yang akan pred(x)? pred(y) : !pred(y)Anda setujui hampir tidak dapat diterima.
leftaroundabout
1
@leftaroundabout: Tidak masalah jika Anda mengetahuinya pred(x)dan pred(y)menggunakan nilai yang sama untuk menunjukkan kebenaran, yang merupakan asumsi aman dalam beberapa bahasa tetapi tidak dalam bahasa lain. Di C, misalnya, Anda mungkin menulis !!pred(x) == !!pred(y).
Keith Thompson
14

Keduanya identik secara fungsional, sehingga yang digunakan adalah masalah selera.

Alasan utama yang saya gunakan == falseadalah bahwa saya telah menemukan bahwa !terlalu mudah untuk diabaikan, ketika melihat kode.

Karena telah digigit parah oleh ini, saya sudah terbiasa membuatnya sangat jelas ketika menguji palsu.


Seandainya operator dinamai notseperti dalam Pascal, saya tidak berpikir ini akan menjadi masalah.

user1249
sumber
5
Untuk alasan ini, proyek C ++ yang saya kerjakan untuk beberapa perangkat lunak perangkat medis memiliki standar pengkodean yang diamanatkan == falsealih-alih !karena alasan yang sama (untuk membuatnya menonjol). Namun tidak ada persyaratan untuk digunakan == true, sehingga nilai bukan nol tetap berfungsi sebagaimana mestinya.
tcrosley
12
Saya selalu menemukan argumen ini tidak meyakinkan - ada tempat lain di C / C ++ / C # / Java / etc di mana gagal untuk melihat satu karakter memiliki dampak yang sama pentingnya pada interpretasi kode; memilih "!" sebagai satu-satunya yang buruk tidak masuk akal bagiku.
Bevan
5
@ Brian Tampaknya Anda belum digigit.
1
Meskipun saya setuju bahwa mengabaikan !mungkin merupakan kesalahan paling sulit dari jenis ini, ini seharusnya IMO tidak menimbulkan kebiasaan menulis ==falsetetapi menulis unit test yang lebih baik.
leftaroundabout
8
@ ThorbjørnRavnAndersen Sebaliknya, saya sudah cukup sering digigit selama bertahun-tahun sehingga saya belajar sendiri untuk membaca setiap karakter . Saya bukan pembuat semua (atau bahkan sebagian besar) dari kode yang saya harus baca setiap hari, jadi setiap konvensi pribadi yang sedang kita bahas di sini memiliki nilai minimal: Saya perlu memahami dengan benar semua kode yang saya baca, tidak hanya hal-hal yang saya tulis.
Bevan
13

Jika condition == falsememang "jauh lebih alami dalam bahasa Inggris" untuk Anda maka saya harus berasumsi bahwa Anda bukan penutur asli. Kalau tidak, saya tidak bisa menjelaskan ini, karena tidak ada yang berbicara seperti itu:

Jika matahari bersinar salah, saya tinggal di rumah.

Bandingkan dengan

Jika matahari tidak bersinar saya tinggal di rumah.

Yang mengatakan, saya setuju bahwa karakter tunggal, ramping !mudah diabaikan dalam kode. Untuk alasan itu, saya lebih suka kata kunci notketika didukung oleh bahasa. C ++ misalnya memang memungkinkan ini meskipun banyak programmer tidak menyadarinya.

Untuk bahasa yang membutuhkan !, saya memberi jarak antara operator dan operan. Ini membuat negasi jauh lebih sulit untuk diabaikan:

if (! condition) { … }

Perhatikan bahwa setiap programmer harus menerjemahkan ini secara otomatis , tanpa berpikir dua kali, untuk "tidak mengkondisikan" di kepala mereka. Memperoleh kelancaran semacam ini dalam membaca idiom kode adalah salah satu langkah pertama untuk menjadi programmer yang baik.

Konrad Rudolph
sumber
7

Ketika saya melihat var == falsesaya selalu bertanya-tanya apakah varboolean atau tipe logika dengan lebih dari dua nilai (dengan, misalnya, a maybedan undefineddan juga truedan false, atau sesuatu seperti nilai sembilan IEEE 1164 ).

Pemrogram
sumber
8
Nilai 3 biasanya "File tidak ditemukan". thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
Groky
6

karena kadang-kadang Anda mungkin menulis boolean = false(dengan kesalahan yang jelas) dan false == booleantidak tampak alami (tidak peduli seberapa bagus praktiknya)

ratchet freak
sumber
Dahulu kala ketika saya pertama kali memulai pemrograman, seorang mentor saya menyarankan agar saya membiasakan diri if( INVALID_HANDLE_VALUE == hFile )untuk menghindari hal-hal seperti itu. Dengan begitu jika Anda tergelincir dan menggunakan satu tanda sama dengan bukan dua, Anda akan mendapatkan kesalahan kompilator. Jelas ini hanya bekerja ketika ekspresi kiri adalah konstan, tetapi itu telah menyelamatkan saya lebih dari sakit kepala daripada yang bisa saya hitung.
Drew Chapin
jika Anda menggunakan alat analisis statis, itu akan menghemat seratus kali lebih banyak sakit kepala, dan Anda dapat mengembalikan hFile==INVALID_HANDLE_VALUE penulisan alami .
Gqqnbig
4

if (!boolean_variable)diterjemahkan menjadi if the condition is not true.

if (boolean == false)diterjemahkan menjadi if the condition not false is true. Karena itu logika terbalik, lebih sulit untuk dipahami.

BЈовић
sumber
3
! Benar berarti tidak benar. ! boolean berarti salah atau tidak benar tergantung pada nilai boolean, yang itu sendiri adalah pembalikan logis.
S.Robins
1
@ S.Robins Saya menemukan nama bodoh boolean untuk variabel boolean. Sesuatu seperti misalnya isVisibleakan menjadi contoh yang lebih baik. Maka if (!isVisible)akan berarti jika tidak terlihat - yang lebih sederhana untuk dipahami if (isVisible==false), yang merupakan logika terbalik. Semoga ini lebih jelas sekarang. Atau, apakah saya salah memahami komentar Anda?
BЈовић
2

Dalam kompiler lama (banyak), saya percaya mereka akan memecah (boolean == false) menjadi 2 tugas register dan kode perbandingan dalam bahasa mesin. Contoh pertama akan dipecah menjadi satu tugas dan operator TIDAK. Dalam hal kinerja, operasi perbandingan akan mengambil sejumlah siklus jam, tergantung pada ukuran register yang dibandingkan, dibandingkan dengan pembalikan bitwise (1 jam) dan akan lebih lambat untuk dijalankan.

Yang sedang berkata, saya percaya kompiler baru menghilangkan ini, jadi itu boleh saja untuk pergi dengan baik.

lcllam
sumber
Menghasilkan kode mesin adalah tugas kompiler, bukan programmer tingkat tinggi ...
CVn
Untuk alasan historis, ini mungkin salah satu alasan mengapa satu metode menjadi lebih disukai daripada yang lain.
Legolas
1

Di tempat kerja saya sering berurusan dengan Boolean yang bisa nol jadi saya akan sering kode kasus ini sebagai

if (value != null && value == true){
    //do something
}

karena saya pribadi merasakan simetri membuatnya lebih mudah dibaca. Terutama jika ada Boolean lain yang sedang diuji juga.

Saya benar-benar tidak peduli dengan satu atau lain cara.

WuHoUnited
sumber
4
jika value == truedemikian tidak ada alasan untuk memeriksa bahwa itu tidak nol. Jika value == nullseharusnya tidak pernah memicu pernyataan if di tempat pertama, maka if (value)seharusnya sudah cukup.
zzzzBov
1
Boolean adalah objek (dalam java) dan karena itu bisa null jadi hanya mengatakan if (value)melempar pengecualian. Saya akan menghargai jika orang yang downvote memberi alasan.
WuHoUnited
3
Saya kebetulan melihat ini, tidak downvote. Boolean null bukan praktik yang baik. Mengapa? karena boolean biasanya mewakili keadaan dari sesuatu yang dihidupkan. Dalam kebanyakan kasus, Anda ingin menyatakan itu salah pada awalnya dan kemudian mengubahnya bersama dengan perilaku. Sangat jarang melihat boolean tidak diinisialisasi.
Aubergine
Saya harus setuju dengan terong di sini, saya sendiri telah jatuh ke dalam kebiasaan buruk (terutama di Jawa) meninggalkan bools tidak diinisialisasi dan akhirnya memeriksa nol. Saya pikir ini lebih merupakan cacat bahasa, namun yang memaksakan cacat pada pengguna. Ketika mendeklarasikan variabel bool baru, maka itu harus default ke false tanpa inisialisasi menurut saya.
2
@ WoHoUnited, bahkan jika nilainya nol, value == truesudah cukup.
zzzzBov
1

Ketika Anda menguji kondisi sebenarnya, masuk akal untuk melakukan hal yang adil if (condition), terutama ketika Anda menerapkan konvensi penamaan variabel boolean dimulai dengan 'is': if (isOpen)sangat jelas dan menggunakan != falseakan berlebihan.

Untuk C / C ++ / Java / dll. programmer, arti dari '!' Operator sepenuhnya berasimilasi, ke titik yang secara otomatis kita miliki 'tidak' dalam pikiran kita ketika kita melihatnya. Jadi memiliki if (!isOpen)sejelas if (_NOT_ isOpen)bagi saya. Tapi Anda tidak cukup familiar, di C / C ++ Anda bisa membuat makro #define _NOT_ !. Tapi percayalah, setelah beberapa tahun ini sama sekali tidak perlu.

Selain itu, selalu lebih baik untuk menguji nilai boolean tanpa membandingkannya dengan literal. Sebagai contoh, berbahaya untuk menguji if (x == true)karena nilai boolean dianggap benar jika bukan nol, dan literal benar hanya memiliki satu nilai spesifik, sehingga x bisa 'benar' (yaitu bukan nol) dan masih perbandingannya bernilai false (karena itu berisi 2 dan literal true adalah, katakanlah, 1.) Tentu saja itu tidak berlaku untuk perbandingan dengan false, tetapi jika Anda tidak menggunakannya saat menguji true, mengapa menggunakannya saat menguji false?

rev, Fabio Ceconello
sumber
Tidak perlu membuat makro C ++ yang Anda usulkan sebagai C ++ sudah mengerti 'tidak'. Terkait: stackoverflow.com/questions/2393673/c-and-or-not-xor-keywords
frozenkoi
Itu benar, tetapi itu hanya kata kunci untuk standar C ++ 0X saja. Sebelum itu, itu hanyalah makro.
Fabio Ceconello
0

Ukuran diperhitungkan ;)

Dalam ekspresi campuran, lebih mudah dibaca:

boolean1 = false
boolean2 = true

p ! boolean1 and ! boolean2
p boolean1 == false and boolean2 == false

Dan terutama untuk ruby ​​contoh di mana ada perbedaan besar:

boolean = nil
p ! boolean         #-> true
p boolean == false  #-> false

nol tidak salah, tetapi juga tidak benar.

knut
sumber
0

Berdasarkan dari pengalaman saya dan jawaban dari pertanyaan saya yang telah Anda tautkan.

Beberapa orang lebih suka menggunakan if (kondisi), karena alasannya lebih pendek untuk menulis. dan bagi saya itu benar-benar masuk akal, misalnya (! isValidated ()) Saya membaca ini sebagai Tidak Divalidasi. tetapi bagi saya itu semua didasarkan pada preferensi pribadi, dan itu tergantung pada struktur logis dari metode isValidated (), apakah itu mengembalikan benar atau salah

KyelJmD
sumber
0

Jika Anda memberi nama variabel dengan benar, maka !booleanitu lebih alami. Bunyinya not booleankepada siapa saja yang cukup programmer untuk membaca kode secara mental.

Lightness Races with Monica
sumber
0

Bagi sebagian orang, semakin cepat suatu makna diungkapkan, semakin baik.

Untuk orang-orang yang memiliki "jika! ..." membandingkan lebih cepat dengan "jika ..." maka harus membaca seluruh kondisi (yang sebenarnya bisa sangat panjang, misalnya (thisThing = thatThing atau sesuatu = hal lain) ATAU ( thinga = thingb dan thinga = thingd), dll.) hanya untuk menemukan == false di akhir.

Memiliki! (Saya benar-benar lebih suka tidak ketika bahasa memungkinkan) tepat di depan mendapat bahasa Inggris 'tidak' untuk kondisi ini di sana lebih cepat.

Masalah ini juga mengarah pada pertimbangan untuk menggunakan untildalam bahasa yang mendukungnya, mis. Lakukan 'barang umum' sampai semuanya selesai. Seperti yang orang lain katakan, ekspresi bahasa alami adalah tujuannya. Saya suka contoh "matahari bersinar" di atas.

bermutu rendah
sumber
0

Alasan lain adalah bahwa jika Anda bekerja dalam basis kode yang menggunakan beberapa bahasa, jika ada satu cara idiomatis untuk melakukan sesuatu yang aman di semua bahasa, itu ide yang cukup bagus untuk melakukannya di mana-mana sehingga Anda membentuk kebiasaan yang baik dan cenderung naik.

Saya tidak dapat memikirkan di mana pun yang if (!variable)(atau yang sepadan seperti if not variabletergantung pada bahasa Anda) tidak aman, sedangkan misalnya if self.is_ready() == False: ...tidak aman dengan python jika self.is_ready()kembali None, sekarang atau di masa depan, yang akan menjadi hal yang sangat masuk akal untuk dilakukan terhadap menunjukkan itu tidak siap karena Nonesama palsu False.

daphtdazz
sumber