Durumu daha iyi hale getirmek için durumumu nasıl yeniden biçimlendirebilirim?


35

Bir şartım var

if(exists && !isDirectory || !exists)
{}

daha fazla anlaşılabilir olması için nasıl değiştirebilirim.


1
var olduğunda yanlıştır isDirectory değeri nedir?
marktani

1
Bool tipi, isDirectory ayrıca BOOL tipi değişkenlerdir
Spynet

5
if (! isDirectory) ... (var ||! var) her zaman doğru olacaktır.
Shark

@Shark - Ya existsve isDirectoryher ikisi de doğrudur?
pasawaya

Başlığı "Bir kişilik problemim var, düzeltmek için fikrimi silebilir miyim" olarak okudum. Evet, yoruldum.
Annan

Yanıtlar:


110

|| değişmeli

if(!exists || (exists && !isDirectory))

eşdeğerdir.

Şimdi var olduğu için her zaman doğrudur, ikinci bölümünüzü ||bırakabilirsiniz &&:

if(!exists || !isDirectory)

Veya bir adım daha ileri gidip şunları yapabilirsiniz:

if(!(exists && isDirectory))

5
Burada ima edilen ancak açıkça belirtilmeyen, &&öncekinin (en azından en iyi bilinen dillerde - istisnalar olabilir) olduğundan daha yüksek önceliğe sahip olmasıdır ||. Böylece a && b || ceşittir, (a && b) || cancak değildir a && (b || c).
Péter Török

27
Bence bu !exists || !isDirectorydaha "anlaşılabilir", çünkü isDirectoryeğer doğru olamaz !exists. Dolayısıyla bir insan olarak “eğer yoksa ya da [varsa ve bir dizin değil” diyeceğiz.
duros

6
Ben tercih ederim! ! sonuncusu üzerinde Dizin.
Apoorv Khurasia

3
||sadece yan etkisi olmayan değerlerde kullanılırsa değişimlidir - örneğin, işlevlerle birlikte kullanılıyorsa, bazı işlevler çağrılmayabilir (kısa devre yaptırma) veya farklı bir sırada farklı bir değer döndürme.
orlp

26
'&&', '||', '==', '! =' 'Nin göreceli önceliğine güvenen ve parantez kullanarak niyetini netleştirmeyen herkes vurulmayı hak ediyor. Tüm dillerde, 'a && b || c 'yazarın birkaç ilave karakter yazmaktan kaçınmak için muhtemelen her şeyi aceleye getirdiğini söyleyen bir yoruma eşdeğerdir.
Brendan

51

Bir süreç olarak bir doğruluk tablosu oluşturmayı öneriyorum:

e = exists
d = isDirectory

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0

Bu basitçe NANDişlemle eşleşir :

!(exists && isDirectory)

Tüm mantık geçitlerinizi hatırlamıyorsanız, wikipedia'nin gerçek tablolarla başlatılması için güzel bir referansı var .


@Hristoffer Hammarström, devlete bağlı isDirectoryolma durumu hakkında önemli bir noktaya geldi exists. Aynı referansa başvurduklarını ve referansın bulunmadığı ve bir dizin olduğu bir duruma sahip olmanın mümkün olmadığını varsayarak , doğruluk tablosu aşağıdaki gibi yazılabilir:

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0

Önemli n/aolmayan bir durumu temsil etmek için kullanılır. Kabul edilebilir indirimler, 1veya 0ile sonuçlanan devletlerde sonuçlanabilir n/a.

Bu düşünceyle, !(exists && isDirectory)bir sonuçlanan hala geçerli bir azalma olduğu 1için !e && d.

Bununla birlikte, !isDirectorysonuçta ortaya çıkan çok daha basit bir azalma 0olacaktır !e && d.


4
Bir sonraki adım bunun isDirectorybağlı olduğunu anlamaktır exists. Her ikisi de bir dizin olamaz ve olamaz.
Christoffer Hammarström

@ChristofferHammarstrom, Bağlam dışı Değişkenlerin aynı şeyi ifade ettiğini varsaymıyorum, ama bu geçerli bir nokta. Sonuç sütunu n/a, devletin ulaşmasının imkansız olduğu yerlerde doldurulmalı ve denklem buna göre azaltılmalıdır.
zzzzBov

Değişkenler iki farklı bağlamdan bahsediyorsa, çok özlüdür ve yeniden adlandırılmaları gerekir.
Christoffer Hammarström

Ancak bir doğruluk tablosu oluşturmak ve değerlendirmek NP tamamlandı!
Thomas Eding 17:12

@ThomasEding, o zaman senin için iki teklifim var, "Teoride, teoride ve pratikte aynı; pratikte, değil." ve "Erken optimizasyon tüm kötülüklerin köküdür."
zzzzBov

22

Daha iyi okunabilirlik için, boole koşullarını yöntemlere çıkarmak isterim:

if(fileNameUnused())
{...}

public boolean fileNameUnused() {
   return exists && !isDirectory || !exists;
}

Veya daha iyi bir yöntem adıyla. Bu yöntemi doğru şekilde adlandırabilirseniz, kodunuzun okuyucusunun boolean koşulunun ne anlama geldiğini çözmesi gerekmez.


Yararlı isimler hakkında bir şeyler söyledikleri için +1. Ama bir yerde şartlıları yeniden biçimlendirmen gerekecek.
Apoorv Khurasia

4
Niyeti hala taşıyan daha az uç bir alternatif, sadece kullanılan koşulu adlandırmaktır:boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Steven

8

Sadece tırnak deneyebilirsiniz no-go dava ve eğer gösterileri yukarı kurtarmak.

while(someCondition) {

    if(exists && isDirectory)
        continue;
        // maybe "break", depends on what you're after.

        // the rest of the code
}

ya da

function processFile(someFile)
{ 
    // ...
    if(exists && isDirectory)
       return false;
    // the rest of the code
    // ...
}

Ayrılma, devam etme ve birden fazla dönüş ifadesi kod kokusu sayılmadı mı?
Freiheit

8
@Freiheit Bağlama bağlıdır. Bazen, girintiyi azaltmak için okunabilirliği artıran erken bir iade ifadesi kullanılır.
marco-fiset

En iyi cevap - karmaşık şartlandırıcılar çok fazla zaman harcarlar ve bunları doğru şekilde anlarlar. Sonuç olarak sinsi böceklere yol açan sıklıkla "okundu" olarak kabul edilir.
mattnz

6

Belirtildiği gibi bir doğruluk tablosu kullanabilirsiniz. İkinci adım , terim sayısını en aza indirgemek için bir KV haritası olabilir .

Boolean cebirinin yasalarını kullanmak başka bir yaklaşımdır:

A = var
B =! İsDirectory
! A =! Var

&& = *
|| = +

[Düzenle]
Daha basit bir dönüşüm, çünkü AND ve OR işlemleri karşılıklı olarak dağıtılıyor:

var &&! isDirectory || ! var
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Düzenle]

var &&! isDirectory || ! var
= A * B +! A
= A * B +! A * 1 // Kimlik
= A * B +! A * (B + 1) // Yok edici
= A * B +! A * B +! A / / Dağıtıcılık ve Kimlik
= B * (A +! A) +! A // Dağıtımcılık
= B * 1 +! A // Tamamlama 2
= B +! A // Kimlik
=! İsDirectory || ! mevcutsa

Veya çift tamamlayıcı ile (!! x = x):

A * B +! A
= !! (A * B +! A)
=! (! (A * B) * A)
=! ((!! A +! B) * A)
=! (! A * A + ! B * A)
=! (0 +! B * A)
=! (! B * A)
= B +! A
=! İsDirectory || ! mevcutsa


Resmi kuralları kullanmak için + 1 (üniversitedeki ilk yılımdan sonra bunlardan birini göreceğimi asla sanmıyorum).
Nemanja Boric


5

"!" Kullanmaktan hoşlanmıyorum. ifadesinde birden fazla koşul olduğunda. Daha okunaklı hale getirmek için kod satırları ekleyeceğim.

doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist) 
   {}

+1 Bu, İngilizce'ye çok daha yakın olan "eğer varsa veya yoksa" olarak okunmayı kolaylaştırır.
Phil


1

Daha önce belirtildiği gibi, durum aşağıdakilere düşürülebilir:

if (!(exists && isDirectory))

Ancak, bir dizin olmanın varoluşu ima ettiğini iddia edeceğim. Eğer öyleyse, durumu şu şekilde azaltabiliriz:

if (!isDirectory)
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.