프로그래밍안드로이드 개발자

코틀린에서 엘비스 연산자 (?:)란 무엇이며, 어떻게 그리고 왜 사용하는가? 그 사용 시 발생할 수 있는 주의사항과 함정은 무엇인가?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문의 배경:

엘비스 연산자 (?:)는 코틀린에서 nullable 값을 안전하게 처리하기 위한 간결한 방법으로 등장했습니다. 이 연산자는 옆에서 보면 엘비스 프레슬리의 헤어스타일과 유사해서 그런 이름이 붙었습니다. 목표는 if (a != null) a else b와 같은 템플릿 코드를 없애고 일상적인 개발을 더 편리하게 만드는 것입니다.

문제:

null일 수 있는 값에 직접 접근하면 런타임 오류 (NullPointerException)가 발생합니다. 따라서 변수에 null이 들어갔을 때 기본값을 우아하게 제공할 수 있는 도구가 필요합니다.

해결 방법:

엘비스 연산자는 nullable 타입에 적용할 수 있습니다. 연산자 왼쪽의 표현식이 null이 아닐 경우 해당 표현식을 반환하고, 그렇지 않으면 오른쪽 표현식을 반환합니다. 이는 코드를 더 간결하고 안전하게 만듭니다.

코드 예시:

fun getLength(str: String?): Int { return str?.length ?: 0 } val result = getLength(null) // result == 0 val result2 = getLength("Hello") // result2 == 5

주요 특징:

  • 명시적인 null 검사를 피할 수 있게 해줍니다.
  • 예외를 던지는 데 사용할 수 있습니다.
  • nullable 타입, 표현식 및 부작용이 있는 함수와 잘 어울립니다.

오해의 소지가 있는 질문들.

엘비스 연산자 오른쪽의 표현식이 부작용이 있을 경우 어떻게 될까요? 항상 실행되나요?

아니요! 오른쪽의 표현식은 왼쪽이 null일 때만 계산됩니다. 이는 함수가 부작용이 있거나 "비용이 많이 드는" 계산을 수행할 경우 중요한 역할을 할 수 있습니다.

코드 예시:

var called = false val x: String? = "test" val y = x ?: run { called = true; "default" } // called는 false, 왜냐하면 run은 실행되지 않기 때문입니다.

엘비스 연산자를 예외를 던지는 데 사용할 수 있나요?

네, 코틀린에서 다음과 같이 작성할 수 있습니다:

fun getLengthStrict(str: String?): Int = str?.length ?: throw IllegalArgumentException("str is null")

str가 null이면 예외가 발생합니다. 이는 데이터 검증을 위한 편리한 메커니즘입니다.

엘비스 연산자를 여러 번 연속으로 "연결"해 사용할 수 있나요?

네, 이는 fallback을 위한 일반적인 접근 방식입니다:

val name = fromDatabase ?: fromCache ?: "Unknown"

이 표현식은 첫 번째 NON-null 값을 반환하거나 "Unknown" 문자열을 반환합니다.

전형적인 오류 및 안티 패턴

  • 복잡하고 긴 엘비스 연산자 체인으로 코드 읽기가 어려워짐
  • 오른쪽 표현식의 부작용을 무시하게 되어 예기치 않은 동작을 유발할 수 있음
  • null을 명시적으로 검사해야 할 때 엘비스를 사용하는 것

실생활 예시

부정적 사례

엘비스를 통한 다중 레벨 중첩 null 체크:

val title = a?.b?.c?.d?.e ?: defaultTitle

장점:

  • 간단한 논리를 위한 간결함

단점:

  • 읽기 어려움
  • 문제가 불분명할 경우 디버깅 어려움

긍정적 사례

단계별 명확한 분해와 이해하기 쉬운 변수 이름:

val deepValue = a?.b val deeperValue = deepValue?.c?.d ?: default

장점:

  • 가독성 향상
  • 추가 검증 또는 로그를 쉽게 추가 가능

단점:

  • 다소 장황할 수 있으며, 초보자에게는 "불필요한" 단계처럼 보일 수 있음