Neden Kullanım! Boolean_variable Over boolean_variable == yanlış


59

Bu soru hakkında bir yorum: Bir yöntemin false döndürüp döndürmediğini denetleme: geçici değişkene sonuç atama ya da yöntem çağrısını doğrudan koşullu olarak yapma? koşulları test ederken !booleanyerine kullanmanız gerektiğini söylüyor boolean == false. Neden? Bana göre boolean == falseİngilizce'de çok daha doğal ve daha açık. Bu sadece stil meselesi ise özür dileriz, ancak bu tercihi için başka sebepler olup olmadığını merak ediyorum !boolean?


28
Yazması daha kısa.
Zenon

39
boolean == trueYapmak gibi : mantıklı değil. İfadelerin içindeki ififadeler tam olarak şudur: ifadeler. Bir şey zaten bir boole ifadesine göre değerlendirilirse, neden bunu değerlendirmeye zorlamak için bir çek eklesin?
25'te

10
@zzzzBov: Um, hayır. Çoğu (C tarzı) programcı bunu yapmaz.
amara

9
@zzzzBov: Yorumunuz belirsiz. Eğer !boolean_variableçoğu C programcısının yaptığı şekilde demek istiyorsan , kabul ediyorum.
Keith Thompson,

29
Ve daha önemlisi, neden kimse yazmak istemiyor boolean != true?

Yanıtlar:


153

Bunun gibi bir çizgi if (!lateForMeeting())gördüğümde, "Toplantıya geç kalmadıysam" , if (lateForMeeting() == false)okuduğumun aksine "Anlaşmaya geç kalmam yanlışsa , " Anlaşılması için geç değilse " olarak okudum. " .

Onlar anlam bakımından özdeştir, ancak eski eşdeğer İngilizce cümlenin nasıl kurulacağına daha yakın.


27
+1 Python'da aslında if not late_for_meeting
yazıyorsunuz

42
"Eğer ___ yanlışsa", "eğer değilse" den daha doğal geliyorsa, o zaman ___ isminin iyileştirilmesi gerekiyor.
Mike DeSimone

12
Perl'de yazabilirsinizunless late_for_meeting
Henrik Ripa

4
@HenrikRipa: Yazabileceğiniz hemen hemen her şey Perl'de yasal bir kod gibi görünüyor. İstediğini yapıp yapmamak, başka bir soru;)
Adam Robinson,

4
@ A-Cube Başlangıçta böyle bir yöntem olmazdı. Bunun yerine, denilen bir yöntem olurdu done(). Çifte negatifler kötü.
kba

97

Yazma == falseve == truegereksizdir. Keyfi uç noktalara da alınabilir. Eğer yazmaya başlarsan

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

Öyleyse neden olmasın

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

Ya da neden olmasın

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

Bu hikayenin ahlaki, eğer conditionbir boolean ifade ise, o zaman eklemenize gerek yoktur == false; operatör !bu içindir;)


Bunu düşünmedim!
ell

51
== falsegereksiz değil, sadece daha ayrıntılı !. OTOH, == truegereksizdir.
dan04 23

4
@ dan04 Haklısın. Ancak, demek istediğim, kötü bir fikir olarak kaldı. (exp1 != exp2)Vs düşünün ((exp1 == exp2) == false). Kuşkusuz bunlar tartışmalı senaryolardır, ancak yine de neredeyse hiçbir zaman doğru veya yanlışla açık karşılaştırmalar yapmamalısınız. Operatör kullanmanız gerektiği gibi, kullanmanız da !=gerekir !.
Andres F.

26
@ dan04: Dil zaten teklif ettiğinde gereksizdir !.
DeadMG

5
@ dan04: Yazdığınız Her zaman bool_expression == bool_literal, == ...gereksiz olduğunu. Doğru ya da yanlış olup olmadığını sınamanız önemli değil. Sadece ortaya çıkan / alternatif blokların sırasındaki değişiklik. Andres'in örnekleri bu noktayı mükemmel bir şekilde gösteriyor. Modern derleyicilerin çoğu, fazlalığı ortadan kaldıracaktır, ancak yine de gereksizdir.
Majesteleri

70

C ve bazı benzer dillerde, için eşitlik boolean ifadeleri karşılaştırarak falseveya truetehlikeli bir alışkanlıktır.

C'de herhangi bir skalar ifade (sayısal veya işaretçi), örneğin bir ifdeyimin koşulu olarak bir boolean bağlamında kullanılabilir . C kuralı if (cond)şuna eşittir if (cond != 0)- yani, sıfır yanlıştır ve sıfır olmayan herhangi bir değer doğrudur. Eğer condişaretçi tiptedir, 0bir boş gösterici sabit olarak kabul edilir; if (ptr)anlamına gelir if (ptr != NULL).

Bu şu demek

if (cond)

ve

if (cond == true)

aynı şeyi kastetmiyorum . İlki condsıfır değilse ilk doğrudur ; İkincisi, yalnızca trueC'ye (varsa #include <stdbool.h>) basit olan eşitse geçerlidir 1.

Örneğin, içinde isdigit()bildirilen işlev , bir rakam ise argüman, sıfır değilse sıfır olmayan <ctype.h>bir intdeğer döndürür 0. Koşulun 42doğru olduğunu belirtmek için geri dönebilir . Karşılaştırma 42 == truebaşarısız olur.

O olur 0için eşitlik karşılaştırılması, böylece yanlış olduğu düşünülen tek değerdir falseçalışacaktır; if (!cond)ve if (cond == false)aynı şeyi yapın. Ancak bundan faydalanacaksanız, karşılaştırmanın falsetamam olduğunu ve karşılaştırmanın trueolmadığını hatırlamak zorundasınız . Daha da kötüsü, karşılaştırmanın çoğu zamantrue işe yarayacağını (örneğin, eşitlik ve ilişkisel operatörler her zaman ya da verimi sağlar ). Bu, bunu kullanarak girdiğiniz herhangi bir hatanın hala tespit edilmesinin zor olabileceği anlamına gelir. (Endişelenmeyin, kodu önemli bir müşteriye demonte ettikten sonra görünecekler.)01

C ++ biraz farklı kurallara sahiptir; örneğin, booldili biraz daha sıkı bir şekilde tümleşiktir ve türe if (cond)dönüşür . Ancak etkisi (çoğunlukla) aynıdır.condbool

Bazı diğer diller, birinin daha iyi davranışta bulunan booleanlar diyebileceği şeye sahiptir; öyle ki cond == trueve cond == false(veya sözdizimi ne olursa olsun) güvenlidir. Öyle olsa bile, gördüğüm her dilin bir vardır notya !operatör; o orada, o yüzden kullansan iyi edersin. Bence kullanmak cond == falseyerine !condya da yapma not cond, okunabilirliği arttırmak. ( !Bir bakışta karakterin görülmesinin zor olabileceği doğru ; Bazen bundan !kaçınmak için boşluk eklerim .)

Sıklıkla sorunu önleyebilir ve kodu hafifçe yeniden düzenleyerek netliği artırabilirsiniz. Örneğin, yerine:

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

yazabilirsin:

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

Bu her zaman daha iyi değildir , ancak olduğu yerde fırsat aramaktan zarar gelmez.

Özet: C ve C ++, eşitlik karşılaştırmalarda için trueve falsetehlikeli aşırı ayrıntılı ve zayıf stili vardır. Diğer birçok dilde, bu tür karşılaştırmalar tehlikeli olmayabilir, ancak yine de aşırı ayrıntılı ve zayıf stillerdir.


Bunun için +1, asıl kullanışlı teknik açıklama ile verilen tek cevaptır.
Mike Nakis

Hala böyle düşünüyorum, programlama dili ne olursa olsun, bunun her zaman == truegüvenli olmadığını varsayıyorum . Bu şekilde daha iyi hissettiriyor.
Dervall

1
@Dervall: Durumun basit olmadığı bir şeyin varsayılması da iyi değildir. Belirli dillerde, booleanların eşitlik karşılaştırmasının sadece güvenli değil aynı zamanda uygun olduğu, örneğin iki yönlü tip çıkarımı olan güçlü, dolaysız döküm tipinde bir sisteme sahip Haskell'de, bazılarının (==True) . façıklığa kavuşturmak için yazabileceği birkaç köşe durumu vardır . -> Booldönüş polimorfik fonksiyonunun başlatılmasını istiyoruz f. Bu daha net not . not . fve ondan daha az garip (f :: a -> Bool).
leftaroundabout

Ayrıca, pred(x)==pred(y)bool döndüren bir işlev için olduğu gibi yapılması kesinlikle uygundur pred. Alternatif pred(x)? pred(y) : !pred(y), kabul edeceğiniz şey olacaktır.
leftaroundabout

1
@leftaroundabout: Eğer biliyorsanız Bu iyi pred(x)ve pred(y)bazı dillerde değil diğerlerinde güvenli bir varsayım olduğu gerçeği göstermek için aynı değeri kullanın. Örneğin, C ile yazabilirsiniz !!pred(x) == !!pred(y).
Keith Thompson

13

Eğer condition == falsegerçekten sizin için “İngilizce'de daha doğal” ise, anadili olmadığınızı varsaymalıyım. Aksi takdirde bunu açıklayamam, çünkü kimse böyle konuşmuyor:

Güneş parlıyorsa yanlıştır evde kalırım.

Şunu karşılaştır

Güneş parlamıyorsa, evde kalırım.

Bununla birlikte, tek, ince !karakterin kodda kolayca gözden kaçabileceğini kabul ediyorum . Bu nedenle, notdili desteklediğinde anahtar kelimeyi tercih ederim . Örneğin C ++ yapar birçok programcı bunun farkında olmasalar da buna izin.

Gereken diller için !operatör ile operand arasına bir boşluk koyarım. Bu, olumsuzlamayı göz ardı etmek çok daha zorlaştırır:

if (! condition) { … }

Her programcının bunu ikinci bir düşünce olmadan otomatik olarak kendi başlarına "koşulsuz" olarak çevirmesi gerektiğine dikkat edin . Kod deyimlerini okurken bu kadar akıcılık kazanmak, iyi bir programcı olmanın ilk adımlarından biri.


13

İkisi işlevsel olarak özdeştir, bu nedenle kullanılacak olanı zevk meselesidir.

Başlıca nedeni ben kullanmak == falseben bulduk ki !kodun bakarken, göz ardı etmek çok kolaydır.

Bununla ciddi bir şekilde ısırıldığını, yanlış için test ederken çok açık bir şekilde yapma alışkanlığım oldu.


Operatör notPascal'daki gibi adlandırılmış olsaydı, bunun bir sorun olacağını düşünmemiştim.


5
Bu çok nedenle, bazı tıbbî cihaz yazılımı için üzerinde çalıştığı bir C ++ proje zorunlu bir kodlama standardı vardı == falseyerine !bu aynı nedenle (o göze çarpması için) için. Ancak kullanma zorunluluğu yoktu == true, bu yüzden sıfır olmayan herhangi bir değer hala olması gerektiği gibi çalıştı.
tcrosley

12
Her zaman ikna edici olmayan bir argüman buldum - C / C ++ / C # / Java / etc içerisinde tek bir karakter görememenin kodun yorumlanmasında benzer derecede önemli bir etkisi olduğu başka yerler de var; "!" Çünkü tek kötü olan bana mantıklı gelmiyor.
Bevan,

5
@bevan Görünüşe göre henüz ısırılmamışsınız.

1
Gözardı !etmenin muhtemelen bu türden en sıkıntılı hata olduğu konusunda hemfikir olmama rağmen, bu IMO'nun yazma alışkanlığına yol açmamasını, ==falsedaha iyi ünite testleri yazmasını sağlamalıdır .
leftaroundabout

8
@ ThorbjørnRavnAndersen Tam tersi - Yıllar boyunca kendime her karakteri okumayı öğrettiğim yeterince ısırıldım . Günden güne okumak zorunda olduğum kodun hepsinin (hatta çoğunun) yazarı değilim, bu yüzden burada tartıştığımız herhangi bir kişisel konvansiyonun asgari değeri vardır: okuduğum tüm kodları doğru anlamam gerekir Sadece yazdığım şeyler.
Bevan


6

çünkü bazen yazabilirsiniz boolean = false(belirgin hatalarla) ve false == booleandoğal görünmüyor (ne kadar iyi bir uygulama olursa olsun)


Uzun zaman önce, programlamaya ilk başladığımda, bir mentor, if( INVALID_HANDLE_VALUE == hFile )böyle şeylerden kaçınmak için alışkanlık yapmamı önerdi . Bu şekilde, iki yerine bir işaret ve eşittir işareti kullanırsanız, bir derleyici hatası alırsınız. Açıkçası bu yalnızca sol ifade bir sabit olduğunda işe yarıyor, ancak bana sayabileceğimden daha fazla baş ağrısı kazandırdı.
Drew Chapin

Statik bir analiz aracı kullanırsanız, size yüzlerce kez daha baş ağrısı kazandırır ve doğa hFile==INVALID_HANDLE_VALUE yazılarını geri yükleyebilirsiniz .
Gqqnbig

4

if (!boolean_variable)çevirir if the condition is not true.

if (boolean == false)çevirir if the condition not false is true. Bunun tersine çevrilmiş bir mantık olduğundan anlaşılması daha zordur.


3
! true, doğru değil demektir. ! boolean , mantıksal olarak tersine çevrilen Boole'nin değerine bağlı olarak ya yanlış ya da doğru değil demektir .
S.Robins

1
@ S.Robins Bir boolean değişkeni için aptal boolean adını bulurum. Örneğin gibi bir şey isVisibledaha iyi bir örnek olacaktır. Öyleyse if (!isVisible)görünür değilse - bunun anlaşılması daha kolay if (isVisible==false)olan, ters mantık anlamına gelir. Umarım şimdi daha açıktır. Yoksa yorumunuzu yanlış mı anladım?
BЈовић

2

(Çok) eski derleyicilerde, 2 kayıt tahsisine (boolean == false) ayrılacağına ve makine dilinde bir kod koyacağına inanıyorum. İlk örnek bir ödev ve bir NOT işlecine ayrılır. Performans açısından karşılaştırma işlemi, karşılaştırılan yazmacının boyutuna bağlı olarak, bitsel bir tersine (1 saat) kıyasla bir dizi saat devri alacaktır ve yürütülmesi daha yavaş olacaktır.

Olduğu söyleniyor, yeni derleyicilerin bununla ortadan kalktığına inanıyorum, öyleyse ikisiyle de gitmek sorun değil.


Makine kodu oluşturmak, derleyicinin işidir, üst düzey programcıların değil ...
CVn

Tarihsel nedenlerden ötürü, bu, bir yöntemin diğerine göre tercih edilmesinin sebeplerinden biri olabilir.
Legolas,

1

İşyerinde sık sık boş olabilecek Boolean'larla uğraşıyorum, bu yüzden bu davayı sık sık kodlayacağım.

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

çünkü simetrinin okumayı kolaylaştırdığını şahsen hissediyorum. Özellikle de test edilen diğer Boole'lar varsa.

Öyle ya da böyle umurumda değil.


4
eğer value == trueöyleyse null olmadığını kontrol etmek için hiçbir sebep yok. Eğer value == nullif ifadesini asla ilk etapta tetiklememesi if (value)gerekiyorsa, yeterli olmalıdır.
zzzzBov

1
Boolean'lar nesnelerdir (java'da) ve bu nedenle boş olabilir, bu nedenle sadece if (value)bir istisna atar. Oy kullanmayan insanlar bir sebep verirse memnun olurum.
WuHoUnited

3
Sadece bunu gördüm, oy kullanmadı. Boolean null iyi bir uygulama değildir. Neden? çünkü boolean genellikle açık olan bir şeyin durumunu temsil eder. Çoğu durumda başlangıçta yanlış olduğunu beyan etmek ve ardından davranışla birlikte değiştirmek istersiniz. Booleanın başlatılmadığını görmek çok nadirdir.
Patlıcan

Burada Patlıcan ile aynı fikirdeyim, kendimi başlatmadan bırakma ve sonra boşluğu kontrol etmeyi bırakma (özellikle Java'da) kötü alışkanlığa düştüm. Bence bu daha çok dilin bir kusuru, ancak bu da bu hatayı kullanıcıya dayatıyor. Yeni bir bool değişkeni bildirirken bence başlatmadan varsayılan değer yanlış olmalıdır.

2
@WuHoUnited, değer null olsa bile, value == trueyeterli olur.
zzzzBov

1

Doğru koşulu test ederken if (condition), özellikle de 'is' ile başlayan boolean değişkenleri adlandırma kuralını uyguladığınızda , bunu yapmak mantıklı olacaktır : if (isOpen)tamamen açık ve != falsekullanımı gereksiz olacaktır.

C / C ++ / Java / etc için. programcı, '!' nin anlamı Operatör, gördüğümüzde zihinlerimizde otomatik olarak 'yok' olduğumuz noktaya kadar tamamen özümsenmiştir. Yani sahip if (!isOpen)olmak if (_NOT_ isOpen)benim için olduğu kadar açık . Ancak yeterince tanıdık değilsiniz, C / C ++ ile bir makro oluşturabilirsiniz #define _NOT_ !. Ama güven bana, birkaç yıl sonra bu tamamen gereksiz.

Bunun yanında, boole değerlerini değişmez değerlerle karşılaştırmadan test etmek her zaman tercih edilir. Örneğin, if (x == true)bir boole değerinin sıfır değilse doğru olduğu kabul edildiğinden ve gerçek anlamdaki gerçekin yalnızca belirli bir değeri olduğundan test etmek tehlikelidir , bu nedenle x 'doğru' (yani sıfır olmayan) olabilir ve yine de karşılaştırma false olarak değerlendirilir (çünkü 2 içeriyor ve değişmez doğru, diyelim ki, 1) Elbette, yanlışla kıyaslama için geçerli değildir, ancak doğru için sınama kullanmıyorsanız, neden yanlış için sınama kullanıyorsanız?


C ++ 'ı önerdiğiniz C ++ makrosunu yapmak' zorunlu 'değildir. Related: stackoverflow.com/questions/2393673/c-and-or-not-xor-keywords
frozenkoi

Bu doğru, ancak yalnızca C ++ 0X standardı için bir anahtar kelime. Ondan önce, sadece başka bir makro vardı.
Fabio Ceconello

0

Boyut önemlidir;)

Karışık ifadelerde okumak daha kolaydır:

boolean1 = false
boolean2 = true

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

Ve özellikle yakut için büyük bir fark olduğu bir örnek:

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

nil yanlış değildir, fakat aynı zamanda doğru değildir.


0

Tecrübelerime ve bağlı olduğum araştırmamın cevaplarına dayanarak.

Bazı insanlar eğer (koşul) kullanmayı tercih ederler, çünkü bunun nedeni, yazmanın daha kısa olmasıdır. ve benim için aslında mantıklı geliyor, örneğin (! isValidated ()) Bunu Validated değil olarak okudum. ama benim için hepsi kişisel tercihlere dayanıyor ve isValidated () yönteminin mantıksal yapısına bağlı, ya doğru ya da yanlış döner.


0

Değişkeninizi doğru bir şekilde adlandırdıysanız !boolean, daha doğaldır. Sanki okur not booleaniçin bir programcı yeter herkese kodunu okumak zihinsel.


0

Bazı insanlar için, bir anlam ne kadar erken olursa o kadar iyi ifade edilir.

"İf! ..." olan insanlar için "if ..." ile daha hızlı karşılaştırırlar, sonra tüm durumu okumak zorunda kalırlar (bu aslında oldukça uzun olabilir, örneğin (thisThing = thatThing veya bir şey = diğer şey) VEYA ( thinga = thingb ve thinga = thingd), vs.) sadece == false komutunu bulmak için.

Sahip olmak! (Aslında dil izin verdiğinde bir tercih etmem). Hemen ön tarafta bu durum için ingilizce 'not' alır.

Bu sorun aynı zamanda untilonu destekleyen dillerin kullanılmasına da dikkat eder, örneğin, bir şey tamamlanana kadar 'ortak şeyler'. Diğerlerinin dediği gibi, doğal dil ifadesi hedefidir. Yukarıdaki "güneş parlıyor" örneğini seviyorum.


0

Başka bir neden, birkaç dil kullanan bir kod tabanında çalışıyorsanız, tüm dillerde güvenli olan bir şey yapmanın aptalca bir yolu varsa, bunu her yerde bu şekilde yapmak iyi bir alışkanlık oluşturmak için iyi bir fikirdir. ve yukarı çıkmak daha az olasıdır.

if (!variable)(Veya if not variablekendi dilinize bağlı gibi eşdeğerlerin ) güvenli olmadığı hiçbir yerde düşünemiyorum , oysa örneğin şimdi ya da gelecekte, geri dönmek için if self.is_ready() == False: ...pythonda güvenli değil . hazır olmadığını gösterir çünkü o kadar falsey .self.is_ready()NoneNoneFalse

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.