1. let은 무엇일까?
let이란 Kotlin에서 제공하는 scope function으로 람다에서 context object를 it을 통해 사용할 수 있고, 람다의 반환값을 반환하는 함수이다.
val person: Person? = Person("algosketch")
fun example() {
person?.let {
println(it.name)
}
}
(이 예제에서 반환 값은 사용하지 않았다) let을 사용하면 person 객체를 it으로 전달 받아 사용 가능하다. 다만 person 객체는 nullable이지만 ?를 통해 null이 아닐 때에만 실행되도록 작성했으므로 it은 nonnull인 Person 타입으로 추론된다. 이처럼 let은 null 체크를 위해 흔히 사용된다.
2. 스마트 캐스트란 무엇일까?
Kotlin에는 smart cast라는 편리한 특성이 있다. 컴파일러가 타입 추론이 가능하다면 해당 타입으로 자동으로 캐스팅된다. 아래 코드는 Person?이었던 person이 Person으로 추론되어 ?나 !! 없이 name에 접근 가능함을 보여준다. 스마트 캐스팅이 되면 아래 사진처럼 IDE에서 초록색 배경으로 표시해 준다.

스마트 캐스트가 안 되는 경우도 있다. 아래 코드는 val을 var로 바꾼 결과이다.

바로 위에서 nonnull을 확인했는데 컴파일러가 멍청한 것 아닌가 생각할 수 있지만, 멀티 스레드 환경에서는 안전하게 타입을 추론할 수 없다는 게 컴파일러의 입장이다. 따라서 스마트 캐스트를 이용하려면 아래와 같이 val(read only)로 선언된 새로운 변수에 담아야 한다.

노란 색 밑줄은 val temp = person ?: return으로 바꿀 것을 권장하는 것이지만, 이해를 위해 예시와 같은 코드를 작성했다.
3. let에서는 그냥 된다.
당연한 말이지만, let은 진입하기 전에 null 처리를 하므로 편하게 쓸 수 있으며 전혀 문제가 없다.
var person: Person? = Person("algosketch")
fun letIsGood() {
person?.let {
println(it.name)
}
}
4. let을 디컴파일 하면?
let으로 작성한 코드를 바이트 코드로 변환 후 다시 java 코드로 디컴파일 하면 아래와 같다.

Person it = var10000;
int var1 = 0;
이 두 줄은 let이라는 scope function을 처리하기 위해 추가된 것이다. 새로운 변수에 담아서 null 체크를 한다는 점에서 예시로 들었던 temp 코드와 동일하다.
5. 그래서 null 체크는?
fun howToCheckNonnull() {
val temp = person ?: return
println(temp.name)
}
개인적으로 위 코드처럼 early return 시키는 게 가장 fun하고 cool하고 sexy하다고 생각한다. early return을 쓰면 null일 때 코드를 더이상 읽지 않아도 된다. if 라면 읽어야 한다. 하지만 early return이 불가능한 상황 - null일 때에도 실행되어야 할 로직이 있는 경우 - 이라면 let을 사용하는 편이다.
'안드로이드' 카테고리의 다른 글
| [Kotlin] Courutine에서 runCatching을 사용할 때 주의할 점 (0) | 2026.08.09 |
|---|---|
| [Kotlin] val은 불변(immutable)이 아니다. (0) | 2026.05.06 |
| [Android Compose] ModalBottomSheet에서 BackHandler 사용하기 (1) | 2026.04.19 |
| 플레이 스토어 심사 거절 (로그인 사용자 인증 정보 세부정보가 영어가 아님) (1) | 2025.07.27 |
| [Android] 컴포즈 내비게이션 딥 다이브 (under the hood of Compose Navigation) (1) | 2024.05.16 |