안전 호출 연산자 '?.'는 Kotlin에서 null 값을 다루기 위한 주요 도구 중 하나로, 잠재적으로 없는 값을 안전하게 사용할 수 있도록 언어의 안전성과 편리함을 높이기 위해 도입되었습니다.
문제의 역사: Java에서는 null 값이 종종 오류(NullPointerException)의 원인이 됩니다. Kotlin은 nullable 및 not-nullable 변수를 명시적으로 구분하는 엄격한 타입 시스템을 도입하고 이를 편리하게 사용할 수 있는 도구와 함께 제공했습니다.
문제: null일 수 있는 객체를 다룰 때 NullPointerException을 피하고, 코드의 가독성과 간결성을 희생하지 않으려면 어떻게 해야 할까요?
해결책: '?.' 연산자는 nullable 변수를 섬세하게 다룰 수 있게 해주며, 객체가 null이 아닐 때만 호출을 수행하고 null일 때는 null을 반환합니다(또는 추가적인 로직을 수행합니다).
코드 예시:
val user: User? = getUser() val name = user?.name // user가 null이 아니면 user.name을 반환, 그렇지 않으면 null user?.printInfo() // user가 null이 아니면 printInfo()가 호출됨
주요 특징:
안전 호출 연산자 '?.'를 할당의 왼쪽에서 사용할 수 있나요?
아니요. '?.' 연산자는 속성이나 변수를 안전하게 설정하기 위해 사용할 수 없으며, 오직 접근이나 호출을 위한 것입니다. 다음은 유효하지 않습니다:
user?.name = "Alex" // 컴파일 오류
속성 할당은 명시적 검사로 안전하게 수행할 수 있습니다:
user?.let { it.name = "Alex" }
null을 만났을 때 안전 호출 연산자의 체인은 무엇을 반환하나요?
체인의 '?.' 중 하나가 null이면 표현식의 결과는 null이 되고, 이후의 안전 호출은 수행되지 않습니다.
예시:
user?.address?.zipCode // user 또는 address가 null일 경우, 결과는 null
Unit을 반환하는 함수와 함께 안전 호출 '?.'를 사용할 수 있나요?
네, 객체가 null이 아닐 때만 호출이 발생하며, 객체가 null일 경우 Unit 대신 null이 반환됩니다.
예시:
user?.clearData() // user가 null일 경우 아무 일도 일어나지 않음
개발자가 null일 수 있는 객체에서 긴 안전 호출 체인 뒤에 '!!'를 사용:
val country = user?.address?.city?.country!!
장점:
단점:
안전 호출을 Elvis 연산자와 함께 사용하여 기본값을 반환:
val country = user?.address?.city?.country ?: "Unknown"
장점:
단점: