코틀린을 시작하면서 신기한 연산자를 정리 했습니다.
기본적으로 kotlin은 null
을 허용하지 않습니다.
다만 명시적으로 null
을 허용할수 있는데요.
// null 할당시 오류
var a: String = "abc" // Regular initialization means non-null by default
a = null // compilation error
// null 명시적 허용 처리
var b: String? = "abc" // can be set to null
b = null // ok
print(b)
// null 인 b의 length에 접근시 오류 발생
val l = b.length // error: variable 'b' can be null
명시적으로 null
을 허용하게 하였다면, 해당 변수의 null
체크는 필수가 되는데요. 코틀린은 이를 어떻게 처리 할까요?
일반적인 null 체크 문법
val b: String? = "Kotlin"
// null 확인 방법 1
if (b != null && b.length > 0) {
print("String of length ${b.length}")
} else {
print("Empty string")
}
// null 확인 2
val l = if (b != null) b.length else -1
안전한 호출
값을 리턴하는게 아니라면, b?.length
사용하면 오류 없이 호출이 가능합니다. 단, null
일 경우 null
을 리턴합니다.
val a = "Kotlin"
val b: String? = null
println(b?.length)
println(a?.length) // Unnecessary safe call
// 결과
null
6
bob?.department?.head?.name
와 같이 계층구조의 데이터를 확인할때 사용하면 안전하게 호출이 가능합니다.
다른 예제
val listWithNulls: List<String?> = listOf("Kotlin", null)
for (item in listWithNulls) {
item?.let { println(it) } // prints Kotlin and ignores null
}
// 결과
Kotlin
또한 할당을 할때도 null 일 경우 해당 function이 호출 되지 않도록 처리 됩니다.
// If either `person` or `person.department` is null, the function is not called:
person?.department?.head = managersPool.getManager()
Elvis operator (엘비스 연산자)
앞서서 null
체크 문법을 기억하시나요?
?:
엘비스 머리모양을 하고 있는 연산자라고 해서 엘비스 연산자라고 불리고 있습니다.
만약 왼쪽 값이 null 이라면 엘비스 연산자 뒤에 오는 값을 return 합니다.
// null 체크
val l: Int = if (b != null) b.length else -1
// 동일 결과 return
val l = b?.length ?: -1
null
체크가 참 쉬워지겠지요?
null 허용된 객체 호출
null
허용된 객체는 일반적으로 호출이 되지 않습니다.
?.
(안전한 호출)이나 !!.
() 연산자를 이용해서 호출해야 하는데요. !!.
의 의미는 null이 아니라는 전제 조건을 설정합니다. 만약 null이면 java.lang.NullPointerException
이 발생합니다.
val b: String? = null
b.length
error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
b!!.length
java.lang.NullPointerException
b?.length
res33: kotlin.Int? = null
// 설사 초기 값을 설정했어도 ?. !!. 없이는 호출이 불가능 합니다.
val b : String? = "abc"
b.length
error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
b.length
안전한 캐스팅
다른 형으로 캐스팅시 ClassCastException
이 발생할 수 있는데요.
val aInt: Int? = a as? Int
이와 같이 호출을 하면 a가 Int 형이 아니면 null을 리턴 합니다.
nullable 리스트에 대한 처리
val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()
filterNotNull
을 이용해서 null을 제외한 리스트를 얻을 수 있습니다.