원문: https://testing.googleblog.com/2023/09/else-nuances.html (Translated by Google Gemini)


함수가 if 문에서 일찍 종료(return)되는 경우, else 절을 사용하는 것과 사용하지 않는 것은 동작상으로는 동일합니다. 하지만 else 절과 가드 절(guard clause, else가 없는 형태)을 적절히 사용하면 코드를 읽는 사람에게 의도를 더 명확하게 전달할 수 있습니다.

함수 구조를 잡는 데 도움이 될 만한 다음 가이드라인들을 고려해 보세요:

특수한 케이스를 미리 처리하기 위해 가드 절(Guard clause)을 사용하세요. 이렇게 하면 나머지 코드는 핵심 로직에 집중할 수 있습니다. 가드 절은 조건을 확인하고 충족되지 않을 경우 빠르게 실패하거나 일찍 반환하여 중첩(nesting)을 줄여줍니다.

Bad#

def parse_path(path: str) -> Path:
  if not path:
    raise ValueError(path is empty.)
  else:
    # 여기에 중첩된 로직이 들어감.
    ...

Good#

def parse_path(path: str) -> Path:
  if not path:
    raise ValueError(path is empty.)
  # 유효한 케이스에 대해 중첩이 필요 없음.
  ...

else가 핵심적인 책임의 일부라면 사용하세요. 각 분기(branch)가 함수의 핵심 책임과 관련이 있다면, 관련된 조건 로직을 동일한 if...else 구조 안에 문법적으로 묶어두는 것이 좋습니다. 이렇게 로직을 그룹화하면 각 조건이 서로 보완적이라는 사실을 강조할 수 있습니다. 앞선 return 문의 결과적인 동작에 의존하여 추론하게 하는 대신, else 문을 통해 명시적으로 상호보완적인 관계를 강조하는 것입니다.

Bad#

def get_favicon(self) -> Icon:
  if self.user.id is None:
    return Icon.SIGNED_OUT
  if self.browser.incognito: return Icon.INCOGNITO
  if not self.new_inbox_items:
    return Icon.EMPTY;
  return Icon.HAS_ITEMS

Good#

def get_favicon(self) -> Icon:
  if self.user.id is None:
    return Icon.SIGNED_OUT
  elif self.browser.incognito:
    return Icon.INCOGNITO
  elif not self.new_inbox_items:
    return Icon.EMPTY
  else:
    return Icon.HAS_ITEMS
  # 뒤에 오는 return은 필요 없으며 허용되지 않음.

관용적인 표현이라면 if...else 대신 switch (또는 유사한) 문을 사용하세요. (Go나 Kotlin의 switch/whenif...else 처럼 불리언 조건을 받을 수 있습니다.)

어떤 패턴을 사용해야 할지 모든 시나리오에서 명확한 것은 아닙니다. 두 가지 스타일 중 하나를 선택할 때 여러분의 최선의 판단을 따르세요. 좋은 경험 법칙은 특수한 케이스라면 가드를 사용하고, 핵심 로직이라면 else를 사용하는 것입니다. 이러한 가이드라인을 따르면 서로 다른 논리적 분기들 사이의 연결 관계를 강조하여 코드의 이해도를 높일 수 있습니다.