상태를 개선하기 위해 상태를 다시 포맷하려면 어떻게해야합니까?


35

조건이 있습니다

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

더 이해하기 쉽도록 수정하려면 어떻게해야합니까?


1
존재하는 경우 isDirectory는 어떤 가치를 가지고 있습니까?
marktani

1
존재는 Bool 타입, isDirectory 또한 BOOL 타입 변수
Spynet

5
if (! isDirectory) ... (존재 ||! 존재)는 항상 참입니다.
상어

@Shark - 어떤 경우 existsisDirectory모두 사실인가?
pasawaya

제목에 "성격에 문제가 있습니다. 문제를 해결하기 위해 마음을 지울 수 있습니까?"라는 제목을 읽었습니다. 네, 피곤 해요
Annan

답변:


110

|| 정류 적이므로

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

동일합니다.

이제 두 번째 부분에는 항상 존재하기 때문에 ||다음을 삭제할 수 있습니다 &&.

if(!exists || !isDirectory)

또는 한 단계 더 나아가 다음을 수행 할 수 있습니다.

if(!(exists && isDirectory))

5
여기에 암시되었지만 명시 적으로 언급되지 않은 것은 &&(최소한 잘 알려진 언어에서는 예외가있을 수 있음)보다 우선 순위가 높습니다 ||. 따라서 a && b || c(a && b) || c같지만 그렇지 않습니다 a && (b || c).
Péter Török

27
나는 그것이 !exists || !isDirectory더 이해할 수 있다고 생각 isDirectory합니다 !exists. 그래서 우리는 인간으로서 "존재하지 않거나 디렉토리가 존재하지 않는다면"이라고 말할 것입니다.
duros

6
나는 선호한다! || ! is 마지막에 대한 디렉토리.
Apoorv Khurasia

3
||예를 들어 함수와 함께 사용되는 경우 일부 함수가 호출되지 않거나 (단락) 다른 값으로 다른 값을 반환 할 수 있습니다.
orlp

26
'&&', '||', '==', '! ='등의 상대적 우선 순위에 의존하고 대괄호를 사용하여 의도를 명확하게 밝히지 않는 사람은 촬영할 가치가 있습니다. 모든 언어에서 'a && b || c '는 저자가 아마도 몇 가지 추가 문자를 입력하지 않기 위해 서두르는 것을 완전히 망쳤다 고 말하는 의견과 같습니다.
Brendan

51

그 과정에서 진리표를 만드는 것이 좋습니다.

e = exists
d = isDirectory

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

이것은 간단히 NANDoperation 입니다 :

!(exists && isDirectory)

모든 논리 게이트를 기억하지 못하는 경우, 위키 백과는 부팅 할 진리표를 잘 참조합니다 .


@Christoffer Hammarström은의 상태에 isDirectory묶여 있는 상태에 대해 중요한 점을 제기했습니다 exists. 그들은 동일한 참조를 참조하는 것이, 그리고 그것을 참조가 존재하지 않는 상태가 수는 없습니다한다고 가정 하고 다음과 같이 진리표를 기록 할 수있는 디렉토리입니다 :

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

n/a문제가되지 않는 상태를 나타내는 데 사용됩니다. 허용 감축에 하나 발생할 수 있습니다 1또는 0결과의 상태에 대해 n/a.

이것을 염두에두고, !(exists && isDirectory)여전히 유효한 축소가 1for !e && d입니다.

그러나 !isDirectory훨씬 간단한 축소가 결과가 0됩니다 !e && d.


4
다음 단계는에 isDirectory따라 다릅니다 exists. 둘 다 디렉토리가 될 수 없으며 존재하지 않을 수도 있습니다.
Christoffer Hammarström

@ChristofferHammarstrom, 문맥 밖에서 변수가 같은 것을 참조한다고 가정 할 수는 없지만 유효한 점입니다. 결과 열은 n/a상태를 달성 할 수없는 장소에 채워 져야하며 그에 따라 방정식이 감소합니다.
zzzzBov

변수가 두 개의 다른 컨텍스트를 참조하면 너무 간결하므로 이름을 바꿔야합니다.
Christoffer Hammarström

그러나 진리표를 작성하고 평가하는 것은 NP- 완료입니다!
Thomas Eding

@ThomasEding, 나는 당신을 위해 두 가지 인용문을 가지고 있습니다. "이론적으로 이론과 실제는 동일하지만 실제로는 그렇지 않습니다." "초기 최적화는 모든 악의 근원입니다."
zzzzBov

22

가독성을 높이기 위해 부울 조건을 메소드로 추출하고 싶습니다.

if(fileNameUnused())
{...}

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

또는 더 나은 분석법 이름으로. 이 메소드의 이름을 올바르게 지정할 수 있으면 코드 리더가 부울 조건의 의미를 알아낼 필요가 없습니다.


유용한 이름에 대해 이야기하면 +1입니다. 그러나 어딘가에 조건부를 다시 포맷해야합니다.
Apoorv Khurasia

4
여전히 의도를 전달하는 덜 극단적 인 대안은 사용 된 조건의 이름을 지정하는 것입니다.boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Steven

8

당신은 그냥 이동 케이스 를 못 박고 그게 나타나면 구제를 시도 할 수 있습니다 .

while(someCondition) {

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

        // the rest of the code
}

또는

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

코드 냄새를 고려한 깨지지 않고 계속하며 하나 이상의 반환 진술이 있습니까?
Freiheit

8
@Freiheit 상황에 따라 다릅니다. 때로는 초기 리턴 문을 사용하여 들여 쓰기를 줄이고 가독성을 향상시킵니다.
marco-fiset

최상의 답변-복잡한 조건은 읽기 및 정확한 이해에 많은 시간을 낭비합니다. 결과적으로 종종 "읽은 상태로 가져 오기"가 교활한 버그로 이어집니다.
mattnz

6

지적한대로 진리표를 사용할 수 있습니다. 두 번째 단계 는 항의 수를 최소화하기위한 KV 맵일 수 있습니다 .

부울 대수 법칙을 사용하는 것도 또 다른 방법입니다.

A = 존재
B =! isDirectory
! A =! 존재

&& = *
|| = +

[편집]
AND와 OR 연산이 서로 분산되어 있기 때문에 더 간단한 변환 :

존재 &&! isDirectory || ! 존재
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ 편집]

존재 &&! isDirectory || ! 존재
= A * B +! A
= A * B +! A * 1 // ID
= A * B +! A * (B + 1) // 소멸자
= A * B +! A * B +! A / / 분포와 동일성
= B * (A +! A) +! A // 분포
= B * 1 +! A // 보완 2
= B +! A // 정체성
=! isDirectory || 존재한다

또는 이중 보수 (!! 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
=! isDirectory || 존재한다


공식적인 규칙을 사용한 +1
Nemanja Boric


5

"!"를 사용하고 싶지 않습니다. 표현식에 둘 이상의 조건이있는 경우 더 읽기 쉬운 코드 줄을 추가하겠습니다.

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

+1 이렇게하면 영어에 훨씬 가까운 "파일이 있거나 존재하지 않는 경우"로 더 쉽게 읽을 수 있습니다.
Phil

이것은 Introduce Explaining Variable 이라는 리팩토링 입니다.
Eddie Gasparian

1

앞에서 설명한 것처럼 조건을 다음과 같이 줄일 수 있습니다.

if (!(exists && isDirectory))

그러나 디렉토리라는 것은 존재를 암시한다고 확신합니다. 그렇다면 조건을 다음과 같이 줄일 수 있습니다.

if (!isDirectory)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.