Kotlin

T?에 대해

주코식딩 2024. 2. 7. 14:55

Optional과 비교

Kotlin의 T?와 비교되는 Java코드는 Optional<T>이다.

Optional<T>와 T?는 비슷해 보이지만 근본이 다르다.

 

T는 T?의 하위 타입이지만 T와 Optional<T>는 하위 타입 관계가 아니다.

간단하게 예제로 살펴보면 다음과 같다.

 

val a : String = "test"
val b : String? = null

b = a

 

String인 a는 String?인 b의 하위 타입이기 때문에 대입 가능하다.

 

반면 Optional은 대입 불가능하다.

 

간단하게 생각해보면 Optional은 null을 더 잘 관리하기 위해 나온 Class이고 '?'는 언어 차원에서 지원하는 연산자이기 때문에 다를 수 밖에 없다.

이러한 근본적인 차이점이 있기 때문에 Intellij에서 제공하는 Java -> Kotlin 마이그레이션 기능을 이용하면 Optional<T>를 T?로 변환해주지 않는다.

 

안전 호출 연산자 (?)

"변수명?.함수(변수)명" 형태로 사용되는 안전 호출 연산자는 코틀린의 주요 기능이다.

안전 호출 연산자가 적용된 변수는 값이 만약 null 이라면 뒤쪽에 적힌 모든 로직을 무시한다.

 

이런식으로 null을 개발단계에서 직접 다루기 때문에 운영단계에서 터지는 null관련 문제로 애를 먹을 일은 없다.

 

T? 활용

not-nullable한 a에 nullable한 b를 대입하려면 별도의 처리가 필요하다.

 

그때 사용하는 것이 "?.let"과 "?:" 이다.

var a: String = "a"
var b: String? = null

a = b ?: throw IllegalArgumentException()
a = b ?: "b"

b?.let {
    println("$it is not null")
    a = it
}

val takeIf = b?.takeIf {
    it.isNotEmpty()
}

a = b!!

 

엘비스 연산자(?:)를 사용하면 간단하게 null일 경우를 제어 가능하다. 

예외 처리를 할 수도 있고 값을 대체하는 것도 가능하다.

 

?.let 는 값이 null이 아닐경우 {}에 작성한 코드가 실행되고 null 일 경우에는 무시된다.

 

?.takeIf 는 조건에 따라 null을 반환하는 함수다.

{} 부분에 false를 return하게 된다면 takeIf라는 변수에 null이 담긴다.

 

그외에 "!!" 연산자도 사용가능한데 Java와 동일하게 동작하도록 하는 연산자다.

값이 null일 경우 접근하려한다면 NullPointorException을 내보낸다.

사용처는 test코드가 아니라면 거의 없다고 보면된다.

 

 

 

'Kotlin' 카테고리의 다른 글

영역 함수(scope functions)  (0) 2024.02.29
수신 객체 지정 람다  (0) 2024.02.29
코틀린의 정적 타입  (0) 2024.02.19
자바에서 코틀린 컬렉션으로  (1) 2024.02.13
확장함수를 사용해 직관적으로 변경하기  (0) 2024.02.07