개발 중 맵의 출발지/도착지를 재설정하는 기능을 구현하면서 Kotlin의 ?. 연산자와 ?: 연산자를 효율적으로 사용할 수 있는 상황이 발생했습니다.
이 글에서는 실제 예시와 함께 두 연산자의 쓰임새를 정리하고, 어떻게 이를 활용해 코드를 간결하고 직관적으로 만들었는지 정리 해 두고자 합니다.
문제 상황: 맵의 마커 업데이트
맵에서 사용자가 새로운 출발지나 도착지를 선택하면, 맵에 표시된 마커(레이블)를 업데이트해야 합니다. 이때 고려해야 할 점은 다음과 같습니다:
- 마커가 이미 존재하는 경우
기존 마커의 위치를 업데이트해야 합니다. - 마커가 존재하지 않는 경우
새로 마커를 추가해야 합니다.
해결 방법: ?. 연산자와 ?: 연산자의 활용
이 문제를 해결하기 위해 아래와 같은 Kotlin 문법을 활용했습니다.
destinationLocationLabel?.moveTo(newLatLng)
?: run {
destinationLocationLabel = map?.labelManager?.layer?.addLabel(
LabelOptions.from(newLatLng)
.setStyles(
setPinStyle(this, R.drawable.marker_destination)
)
.setTexts(LabelTextBuilder().setTexts("도착"))
)
}
코드 설명
1. ?. 연산자: Null-Safe 호출
destinationLocationLabel?.moveTo(newLatLng)
- 의미: destinationLocationLabel이 null이 아닌 경우에만 moveTo(newLatLng) 메서드를 호출합니다.
- 사용 이유: 기존에 마커가 존재하면 마커를 옮기기만 하면 되기 때문입니다.
2. ?: 연산자: Elvis 연산자
?: run {
destinationLocationLabel = map?.labelManager?.layer?.addLabel(...)
}
- 의미: destinationLocationLabel?.moveTo(newLatLng)의 결과가 null이라면, 즉 마커가 존재하지 않는 경우 새 마커를 추가합니다.
- 사용 이유: destinationLocationLabel이 null일 때만 새로 마커를 추가해야 하기 때문입니다.
동작 흐름
- 마커가 이미 존재하는 경우
- destinationLocationLabel?.moveTo(newLatLng)가 실행됩니다.
- ?. 연산자 덕분에 moveTo(newLatLng)가 안전하게 호출됩니다.
- Elvis 연산자 ?: 이후의 코드는 실행되지 않습니다.
- 마커가 존재하지 않는 경우
- destinationLocationLabel?.moveTo(newLatLng)의 결과가 null이 됩니다.
- Elvis 연산자 ?: 이후의 코드가 실행됩니다.
- 새 마커를 추가하고, 그 객체를 destinationLocationLabel에 저장합니다.
왜 ?. 연산자와 ?: 연산자가 적합한가?
이 두 연산자를 사용하면 다음과 같은 장점이 있습니다:
- 안전한 Null 처리
- ?. 연산자를 통해 객체가 null인지 여부를 매번 확인하는 반복적인 코드를 줄일 수 있습니다.
- 간결한 코드
- ?: 연산자를 사용하면 if-else 문 없이 null 처리와 기본 동작을 한 번에 정의할 수 있습니다.
- 가독성 향상
- 한눈에 "마커가 존재하지 않으면 새로 추가한다"는 로직을 이해할 수 있습니다.
- 한눈에 "마커가 존재하지 않으면 새로 추가한다"는 로직을 이해할 수 있습니다.
비슷한 코드 없이 작성했다면?
아래는 동일한 기능을 if-else로 작성한 예입니다.
if (destinationLocationLabel != null) {
destinationLocationLabel.moveTo(newLatLng)
} else {
destinationLocationLabel = map?.labelManager?.layer?.addLabel(
LabelOptions.from(newLatLng)
.setStyles(
setPinStyle(this, R.drawable.marker_destination)
)
.setTexts(LabelTextBuilder().setTexts("도착"))
)
}
- 위 코드는 동작은 동일하지만, if-else로 인해 가독성이 떨어지고 코드가 길어집니다.
- Kotlin의 ?. 연산자와 ?: 연산자를 사용하면 이러한 문제를 해결할 수 있습니다.
반응형
'Android > Kotlin' 카테고리의 다른 글
[Android/Kotlin] removeAt: 요소 제거와 반환 동작 이해 (1) | 2025.01.17 |
---|---|
[Android/Kotlin] sortWith vs sortedWith: 차이와 사용법 (0) | 2025.01.02 |
[Android/Kotlin] 코틀린에서 비동기 콜백 처리하기: 람다와 인터페이스 방식 비교 (0) | 2024.10.30 |
[Android/Kotlin] 람다를 사용하는 두 가지 방식: 함수 인자와 마지막 인자 문법 (0) | 2024.09.09 |
[Kotlin] apply 문법 이해하기 (0) | 2024.06.24 |