Boole kontrolleri için xor operatörünü kullanmak iyi bir uygulama mudur? [kapalı]


150

Ben şahsen gibi dışlayan ya da , ^bunun nedeni onun özlülük boole çeklerin bağlamında mantıklı operatörü. Yazmayı çok tercih ederim

if (boolean1 ^ boolean2)
{
  //do it
}

göre

if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
  //do it
}

ancak genellikle diğer deneyimli Java geliştiricilerinden (sadece yeni başlayanlar değil) karışık görünümler alıyorum ve bazen sadece bitsel işlemler için nasıl kullanılması gerektiğine dair yorumlar yapıyorum.

^Operatörün kullanımı ile ilgili en iyi uygulamaları merak ediyorum .

Yanıtlar:


298

Bunun !=yerine kullanabilirsiniz .


36
" bool1 ^ bool2 ^ bool3bool1 != bool2 != bool3
Sorun

4
Beynim acıyor. Öyleyse! = Yanlış sonuçlar verebilir mi?
vemv

27
@vemv, s !=için doğru sonuçlar verir boolean( Booleans için değil, bu yüzden dikkatli olun). Yine de her zaman hoş değil, örneğin (some != null) != (other != null)çok okunabilir değil. Parçaları açık booleanlarda ayıklamanız veya !=ayrı bir yöntemle ayıklamanız gerekir .
ivant

23
Neden: a ^ b=> "a veya b ama her ikisi de değil", a != b=> "a b'ye eşit değil". (@RobertGrant ne dedi). Çoğu insan, xor'un ne olduğunu biliyorsa ilkini daha kolay anlardı (bu, bilgisayar alanında olup olmadığınızı bilmek için oldukça yararlıdır ...)
Harold R. Eason

2
@ HaroldR.Eason burada nitpicking önemli: a != b=> "a b için KİMLİK DEĞİL "
Mario Reutter

27

Bence kendi sorunuzu cevapladınız - eğer insanlardan garip bir görünüm alırsanız, muhtemelen daha açık bir seçenekle gitmek daha güvenlidir.

Yorum yapmanız gerekiyorsa, muhtemelen daha ayrıntılı sürümle değiştirmekten ve ilk etapta insanlara soruyu sormamanız daha iyidir.


6
Sizi iddia edebilirim, (boolean1 && !boolean2) || (boolean2 && !boolean1)gerçek hayattaki bir uygulama kodunu ciddi bir şekilde yazdığınızda, benden garip görünümler alacaksınız …
Holger

17

Benzer konuşmalarmın olduğunu çok anlıyorum. Bir yandan, hedefinize ulaşmak için kompakt ve verimli bir yönteminiz var. Öte yandan, ekibinizin geri kalanının anlamayabileceği bir şey var, bu da gelecekte bakımını zorlaştırıyor.

Genel kuralım, kullanılan tekniğin, programcıların genel olarak bilmesini beklemenin makul bir şey olup olmadığını sormaktır. Bu durumda, programcıların boolean operatörlerini nasıl kullanacaklarını bilmelerini beklemenin mantıklı olduğunu düşünüyorum, bu nedenle bir if ifadesinde xor kullanmak iyidir.

İyi olmayan bir şeye örnek olarak, iki değişkeni geçici bir değişken kullanmadan değiştirmek için xor kullanma hilesini kullanın. Bu herkesin aşina olmasını beklemem bir hile, bu yüzden kod inceleme geçmek olmaz.


14

Eğer yorum yaptıysanız iyi olacağını düşünüyorum, örneğin // ^ == XOR.


10

Her zaman ona ayrıntılı bir isim vermek için bir fonksiyona sarabilirsiniz:

public static boolean XOR(boolean A, boolean B) {
    return A ^ B;
}

Ama bana öyle geliyor ki, ^ operatörünün Google için ne için olduğunu bilmeyen herkes için çok zor olmazdı. İlk defa hatırlamak zor olmayacak. Başka kullanımlar istendiğinden, bit maskeleme için XOR'u kullanmak yaygındır.

Üçüncü bir geçici değişken kullanmadan iki değişkenteki değerleri değiştirmek için XOR'u da kullanabilirsiniz .

// Swap the values in A and B
A ^= B;
B ^= A;
A ^= B;

İşte XOR takasıyla ilgili bir Stackoverflow sorusu .


6

Son zamanlarda işteki bir JavaScript projesinde bir xor kullandım ve neler olduğunu açıklamak için 7 satır yorum ekledim. Bu bağlamda XOR kullanarak gerekçesi (terimler bu biri term1iki değil üç değeri üzerinde alabilir aşağıdaki örnekte) undefined, trueya da falsebaşka bir süre ( term2) olabilir trueya da false. undefinedVakalar için ek bir kontrol eklemek zorunda kalırdım, ancak xor ile, aşağıdakiler yeterliydi, çünkü xor, ilk terimin bir Boole olarak değerlendirilmesini zorunlu kıldı ve şu şekilde undefinedmuamele görmesine izin verdi false:

if (term1 ^ term2) { ...

Sonunda, biraz abartılıydı, ama yine de orada bir çeşit Paskalya yumurtası olarak tutmak istedim.


IMHO, örtük dönüşüme güvenmek yerine, karşılaşılması olağandışı bir durumda, dönüşümü açık yapmak daha iyidir . Ve genel olarak, "tanımsızların yanlış muamele görmesine izin vermek" her dilde tartışmalı bir uygulamadır. Java tri-state değerleri kullanmadım, ancak C #, bir bool? adeğer açıkça gerçek kullanım için test edilebilir a == true- java benzer bir teknik var mı? C # 'da, iki bool?değer verildiğinde , "null değerini false olarak kabul et" yol açar (a == true) ^ (b == true). Eşdeğer bir formül (a == true) != (b == true). Java'da benzer bir şey yapabilir misin?
Araç ÜreticisiSteve

5
if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
  //do it 
} 

IMHO bu kod basitleştirilebilir:

if(boolean1 != boolean2) 
{ 
  //do it 
} 

5

Kod netliği göz önünde bulundurulduğunda, bence XOR'u boole denetimlerinde kullanmak, XOR bitsel operatörü için tipik bir kullanım değildir. Deneyimlerime göre, Java'daki bitsel XOR genellikle bir maske flag toggledavranışı uygulamak için kullanılır :

flags = flags ^ MASK;

BuVipan Singla'nın makalesi, kullanım durumunu daha ayrıntılı olarak açıklamaktadır.

Örneğinizde olduğu gibi bitsel XOR kullanmanız gerekiyorsa, neden kullandığınızı açıklayın, çünkü neden kullandığınızı anlamak için bitsel okuryazar bir kitlenin parçalarında durması gerekebilir.


-1

Ben şahsen özünden dolayı "boolean1 ^ boolean2" ifadesini tercih ediyorum.

Sizin durumunuzda olsaydım (bir ekipte çalışıyordum), "boolean1 ^ boolean2" mantığını "isDifferent (boolean1, boolean2)" gibi açıklayıcı bir isimle kapsülleyerek bir uzlaşma bulurdum.

Örneğin, "boolean1 ^ boolean2" yerine "isDifferent (boolean1, boolean2)" ifadesini şöyle çağırırsınız:

if (isDifferent(boolean1, boolean2))
{
  //do it
}

"İsDifferent (boolean1, boolean2)" işleviniz şöyle görünür:

private boolean isDifferent(boolean1, boolean2)
{
    return boolean1 ^ boolean2;
}

Tabii ki, bu çözüm, görünüşte yabancı bir işlev çağrısının kullanılmasını gerektirir; bu, kendi içinde En İyi Uygulamalar incelemesine tabidir, ancak ayrıntılı (ve çirkin) ifadeden kaçınır (boolean1 &&! Boolean2) || (boolean2 &&! Boolean1) "!


-2

Kullanım şekli bunu haklı çıkarıyorsa, neden olmasın? Ekibiniz operatörü hemen tanımıyor olsa da, zaman kazanabiliyordu. İnsanlar her zaman yeni kelimeler öğrenir. Neden programlamada olmasın?

Belirtebileceğim tek uyarı, "^" ifadesinin ikinci boole denetiminizin kısa devre semantiğine sahip olmamasıdır. Gerçekten kısa devre semantiğine ihtiyacınız varsa, statik bir util yöntemi de çalışır.

public static boolean xor(boolean a, boolean b) {
    return (a && !b) || (b && !a);
}

16
Xor ile herhangi bir kısa devre göremiyorum - sonucu değerlendirmek için hem a hem de b'yi bilmelisiniz.
Thelema

7
Ayrıca, argümanlar çağrı zamanında değerlendirilir, böylece hiçbir kısa devre gerçekleşmez.
erikkallen

3
Ek olarak, xor, makine düzeyinde tek bir işlem olmalıdır.
Ogre Psalm33

Muhtemelen kısa devre değerlendirmesi ile tembel değerlendirme arasındaki farkı aramalısınız. Kısa devre değerlendirmesi, aksi takdirde sıfıra bölme gibi çalışma zamanı hatalarına neden olabilecek çağrıları engelleyen bir kod stilidir. C'de bu ´if (payda! = 0 && pay / payda) ´ olabilir, bu da içinde sıfıra bölünmeyi önlemek için tembel değerlendirme kullanır. Cevabınız da tamamen spekülatif.
Martin

2
Dürüst olmak gerekirse, bir işlev yazan bir programcı xor xor operatörünün tam olarak ne yaptığını ancak dolambaçlı bir şekilde yaptığı , aklımda yeni kullanılan bir programcıdan daha fazla soru (özellikle yetkinlik hakkında) getirecektir ^.
Stijn de Witt

-3

! = iki değişkeni karşılaştırmak için uygundur. Bununla birlikte, çoklu karşılaştırmalar ile çalışmaz.


-3

Bitsel bir operatör olarak, xor, onu değiştirmek için diğer araçlardan çok daha hızlıdır. Performans açısından kritik ve ölçeklenebilir hesaplamalar için, xor zorunludur.

Öznel kişisel fikrim: Booleanlar için herhangi bir amaç için eşitlik (== veya! =) Kullanmak kesinlikle yasaktır. Bunu kullanmak temel programlama etiği ve temellerinin eksikliğini gösterir. Sana şaşkın bakışlar veren herkes, boole cebirinin temellerine geri gönderilmelidir (burada "inanç nehirlerine" yazmak istedim) :).


1
JIT, bir mantıksal ifadeyi diğeriyle değiştirmek gibi anahtar deliği (küçük) optimizasyonlarında son derece iyi.
David Leppik

1
Ayrıca, ^ öncelikle bir Boolean (mantık) operatörü değil, bitsel bir operatördür. Okuyucunun yavaşlamasını söyler, çünkü işaret hataları olması muhtemeldir. ^ İçin! = Kullanırsanız, C'de program yaparsanız gerçekten berbat olacaksınız. Bitwise operatörleri, okuyucularınıza (siz de dahil kodunuzu hata ayıklayanlara) yavaşlamak ve işaret hataları aramak için bir işarettir. . Ve zor olabilirler. Örneğin, Java'nın% 'sının C veya Python'daki gibi gerçek modulo olmadığını biliyor muydunuz? Bir keresinde C, JavaScript ve Python'da aynı koşan bir kod snippet'im vardı, ancak Java'da değil.
David Leppik

6
Bu nasıl değerlendirildi? Her şeyden önce, Java XOR ve! = 'De derlenir [ stackoverflow.com/a/4175512/202504 Tam (aynı koda)), ikincisi eşitlik için montajcı testinde bile ve her biri tek basit işlemlerdir. İfadenizi yedeklemek için herhangi bir numaranız var mı?
jmiserez

-4
str.contains("!=") ^ str.startsWith("not(")

benim için daha iyi görünüyor

str.contains("!=") != str.startsWith("not(")
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.