여러 조건으로 if 문을 형식화하는 가장 좋은 방법


88

두 개 이상의 조건을 기반으로 일부 코드를 실행하려면 if 문을 형식화하는 가장 좋은 방법은 무엇입니까?

첫 번째 예 :-

if(ConditionOne && ConditionTwo && ConditionThree)
{
   Code to execute
}

두 번째 예 :-

if(ConditionOne)
{
   if(ConditionTwo )
   {
     if(ConditionThree)
     {
       Code to execute
     }
   }
}

각 조건이 긴 함수 이름이나 그 밖의 것일 수 있다는 점을 염두에두고 이해하고 읽는 것이 가장 쉽습니다.


이 페이지의 아무도 "fast"또는 "performance"부분 문자열을 언급하지 않는 것이 유감입니다. 그게 제가 여기서 배우러 온 것입니다.
Dreamspace President

답변:


131

나는 옵션 A를 선호한다

bool a, b, c;

if( a && b && c )
{
   //This is neat & readable
}

특히 긴 변수 / 방법 조건이있는 경우 줄 바꿈 만하면됩니다.

if( VeryLongConditionMethod(a) &&
    VeryLongConditionMethod(b) &&
    VeryLongConditionMethod(c))
{
   //This is still readable
}

더 복잡한 경우 if 문 외부에서 조건 메서드를 별도로 수행하는 것이 좋습니다.

bool aa = FirstVeryLongConditionMethod(a) && SecondVeryLongConditionMethod(a);
bool bb = FirstVeryLongConditionMethod(b) && SecondVeryLongConditionMethod(b);
bool cc = FirstVeryLongConditionMethod(c) && SecondVeryLongConditionMethod(c);

if( aa && bb && cc)
{
   //This is again neat & readable
   //although you probably need to sanity check your method names ;)
}

IMHO 옵션 'B'의 유일한 이유 else는 각 조건에 대해 실행할 별도의 기능 이있는 경우 입니다.

예 :

if( a )
{
    if( b )
    {
    }
    else
    {
        //Do Something Else B
    }
}
else
{
   //Do Something Else A
}

나는 그것을 좋아한다. 메서드가 이미 존재하고 부울 값을 반환하지 않는 한, 메서드 아이디어의 열렬한 팬은 아니지만.
Thomas Owens

2
두 번째 예에서 이유없이 모든 것을 평가하지 않습니까?
Odys dec

조건 앞에 '&&'를 사용합니다. 예제에서와 같은 문자 길이를 가진 조건을 갖는 것은 어렵습니다.
Darkov

28

다른 답변은 첫 번째 옵션이 일반적으로 가장 좋은 이유를 설명합니다. 그러나 여러 조건이있는 경우 옵션 1에서 조건 검사를 수행하는 별도의 함수 (또는 속성)를 만드는 것이 좋습니다. 이렇게하면 최소한 좋은 메서드 이름을 사용할 때 코드를 훨씬 쉽게 읽을 수 있습니다.

if(MyChecksAreOk()) { Code to execute }

...

private bool MyChecksAreOk()
{ 
    return ConditionOne && ConditionTwo && ConditionThree;
}

조건은 지역 범위 변수에만 의존하므로 새 함수를 정적으로 만들고 필요한 모든 것을 전달할 수 있습니다. 믹스가 있으면 현지 물건을 전달하십시오.


2
나는이 이후에 조건을 추가하는 가장 효과적이고 쉬운 것으로 판명
pbojinov

+1 처음에는 눈썹을 올렸는데이게 정말 정답 임호. 그 부울 isOkToDoWhatever을 속성으로 사용하는 것은 많은 의미가 있습니다.
grinch

1
그러나 이것은 읽을 수 있어야하는 다른 곳 으로도 동일한 복잡한 조건을 이동 하므로 우리는 이것으로 다시 원점으로 돌아갑니다. if문 가독성 에 관한 것이 아니라 조건 가독성 에 관한 것입니다.
Robert Koritnik

@RobertKoritnik 나는 당신이 말하는 것을 이해하지만 독자가 한 번에 고려해야 할 복잡성을 줄 였기 때문에 우리가 원점으로 돌아 왔다고 생각하지 않습니다. 그녀는 조건을 볼 수도 있고, 조건에 좋은 이름이있는 조건을 사용하여 코드를 볼 수도 있습니다. 적어도 나는 종종 이것을 더 쉽게 찾을 수 있지만 때로는 모든 세부 사항을 한곳에 모으는 것이 좋습니다. 항상 그렇듯이 상황에 따라 다릅니다.
Torbjørn

좋은 메서드 이름과 논리 리팩토링을 활용하는 좋은 점입니다.
JB Lovell

10

첫 번째 예는 "읽기 쉬움"입니다.

사실, 제 생각에는 "else logic"을 추가해야 할 때마다 두 번째 것을 사용해야하지만 간단한 Conditional의 경우 첫 번째 맛을 사용하십시오. 조건의 길이가 걱정된다면 항상 다음 구문을 사용할 수 있습니다.

if(ConditionOneThatIsTooLongAndProbablyWillUseAlmostOneLine
                 && ConditionTwoThatIsLongAsWell
                 && ConditionThreeThatAlsoIsLong) { 
     //Code to execute 
}

행운을 빕니다!


9

이 질문에 대한 답변은 지금까지 순전히 "구문 적"근거로 결정을 내려야하는 것처럼 답변되었습니다.

if 내에서 여러 조건을 배치하는 방법에 대한 정답은 "의미론"에도 의존 해야 합니다. 따라서 조건은 "개념적으로"결합되는 것에 따라 분류되고 그룹화되어야합니다.

두 테스트가 실제로 동일한 동전의 양면 인 경우 예. (x> 0) && (x <= 100)이면 같은 줄에 함께 넣으십시오. 다른 조건이 개념적으로 훨씬 더 먼 경우 예. user.hasPermission (Admin ()) 그런 다음 자체 줄에 넣으십시오.

예 :

if user.hasPermission(Admin()) {
   if (x >= 0) && (x < 100) {
      // do something
   }
}

7
if (   ( single conditional expression A )
    && ( single conditional expression B )
    && ( single conditional expression C )
   )
{
   opAllABC();
}
else
{
   opNoneABC();
}

다음과 같이 if-else 문에서 여러 조건식 형식을 지정합니다.

  1. 가독성 향상 :
    a. 먼저 표시된 표현식의 모든 이진 논리 연산 {&&, ||}
    b. 각 이진 연산의 두 조건부 피연산자는 수직으로 정렬되기 때문에 분명
    합니다. c. 중첩 된 논리 표현식 연산은 절 내부의 중첩 문과 마찬가지로 들여 쓰기를 사용하여 명확 해집니다.
  2. 명시적인 괄호가 필요합니다 (연산자 우선 순위 규칙에 의존하지 않음)
    . 이것은 일반적인 정적 분석 오류를 방지합니다.
  3. 쉽게 디버깅 할 수 있습니다
    . //
    b로 개별 단일 조건부 테스트를 비활성화 합니다. 개별 테스트
    ceg 직전 또는 후에 중단 점 설정 ...
// disable any single conditional test with just a pre-pended '//'
// set a break point before any individual test
// syntax '(1 &&' and '(0 ||' usually never creates any real code
if (   1
    && ( single conditional expression A )
    && ( single conditional expression B )
    && (   0
        || ( single conditional expression C )
        || ( single conditional expression D )
       )
   )
{
   ... ;
}

else
{
   ... ;
}

이것이 제 방법입니다. 내가 가진 유일한 문제는 이것을 옵션으로 제공하는 코드 미화
기를


3

첫 번째는 더 쉽습니다. 왜냐하면 왼쪽에서 오른쪽으로 읽으면 "If something AND somethingelse AND somethingelse THEN", 이것은 이해하기 쉬운 문장입니다. 두 번째 예는 "If something THEN if something else, THEN if something else THEN"로, 어색합니다.

또한 절에 일부 OR를 사용하고 싶은지 고려하십시오. 두 번째 스타일에서는 어떻게 수행 하시겠습니까?


0

Perl에서는 다음과 같이 할 수 있습니다.

{
  ( VeryLongCondition_1 ) or last;
  ( VeryLongCondition_2 ) or last;
  ( VeryLongCondition_3 ) or last;
  ( VeryLongCondition_4 ) or last;
  ( VeryLongCondition_5 ) or last;
  ( VeryLongCondition_6 ) or last;

  # Guarded code goes here
}

조건 중 하나라도 실패하면 블록 후에도 계속됩니다. 블록 이후에 유지하려는 변수를 정의하는 경우 블록 전에 변수를 정의해야합니다.


1
Perlish처럼 보입니다- "it does WHAT?" 감각;)하지만 일단 익숙해지면 실제로 읽을 수 있습니다.
Piskvor는

-2

나는 오랫동안이 딜레마에 직면 해 왔지만 여전히 적절한 해결책을 찾을 수 없습니다. 제 생각에 좋은 방법은 먼저 조건을 제거하려고 시도하는 것이므로 갑자기 5 개를 비교하지 않습니다.

대안이 없다면 다른 사람들이 제안한 것처럼-그것을 별도의 이름으로 나누고 이름을 줄이거 나 그룹화하십시오. 예를 들어 모두가 참이어야한다면 "x 배열에 거짓이 없으면 실행"과 같은 것을 사용하십시오.

모든 것이 실패하면 @Eoin Campbell은 꽤 좋은 아이디어를주었습니다.


이것은 이미 존재하는 답변에 새로운 것을 추가하지 않습니다.
jerney

-4

조건이 정말 복잡 할 때 다음 스타일을 사용합니다 (PHP 실제 예).

if( $format_bool &&
    (
        ( isset( $column_info['native_type'] )
            && stripos( $column_info['native_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['driver:decl_type'] )
            && stripos( $column_info['driver:decl_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['pdo_type'] )
            && $column_info['pdo_type'] == PDO::PARAM_BOOL
        )
    )
)

여러 수준을 중첩하는 것보다 더 좋고 읽기 쉽다고 생각합니다 if(). 그리고 이와 같은 경우에는 복잡한 조건을 조각으로 나눌 수 없습니다. 그렇지 않으면 if() {...}블록 에서 동일한 문을 여러 번 반복해야하기 때문 입니다.

또한 코드에 "공기"를 추가하는 것이 항상 좋은 생각이라고 생각합니다. 가독성을 크게 향상시킵니다.

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