kotlin

Kotlin의 Null 처리 방법

메모는나의열정 2022. 12. 20. 01:05
반응형

1. Kotlin의 Null 처리 사용 가이드

이글에서는 Kotlin 언어에 NULL 사용 방법을 알아보겠습니다. Kotlin은 변수에 NULL을 허용할지 안할지를 미리결정하여 변수를 선언합니다. 또한 자바보다 NULL에대한 코드를 짧고 가독성 좋게 작성할 수 있습니다. NULL처리에 대해 추가 라이브러리가 필요하지 않습니다.

2. 메이븐 종속성

먼저 테스트를 하려면 아래와 같이 코틀린 kotlin-stdlib Maven 종속 항목 을 추가해야 합니다.

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
    <version>1.1.1</version>
</dependency>

3. Null 허용 변수 및 Null 허용이 아닌 변수를 다루는 방법

Kotlin에는 컴파일 타임에 개발자에게 프로그램의 정확성에 대한 정보를 제공하기 위해 컴파일레벨에서 크게 null 허용 과 null 허용이 불가한 변수를 선언할 수 있습니다. 기본적으로 코틀린은 변수에 NULL을 선언할 수 없습니다. 예를들면 아래와같습니다.

var a: String = "value"

assertEquals(a.length, 5)

위 a라는 변수에는 NULL값을 할당할 수 없씁니다. 그리고 만약 NULL을 할당하면 컴파일 에러가 발생할 것 입니다.

만약 NULL값을 할당하기를 원한다면 아래와 같이 변수옆에 ?와함께 변수를 할당해야합니다.

var b: String? = "value"

그런다음 아래와같이 NULL을 넣을 수 있습니다

b = null

자바나 코틀린에서 개발자는 B에 변수에 접근하려면 아래와같이 NULL인지 아닌지 확인을 하고 접근해야합니다.

if (b != null) {
    println(b.length)
} else {
    assertNull(b)
}

4. 안전한 호출

하지만 위와같은 방식으로 변수에 NULL이 있는지 없는지 확인하면서 접근해야한다면 코드가 엄청 난잡해질것입니다.

먼저 아래와같은 클래스를 선언하겠습니다.

data class Person(val country: Country?)

data class Country(val code: String?)

country, code 코드 둘다 NULL이 할당 가능합니다. 만약 위 code 변수에 접근하기위해서는 기존 자바에서는 if문을 통한 NULL검사를 통해 code값을 알아낼 수 있었지만 코틀린같은경우 아래와같이 쉽게 ?연사자를 통해 code 값에접근할 수 있습니다.

val p: Person? = Person(Country("ENG"))

val res = p?.country?.code

assertEquals(res, "ENG")

변수 p 가 null 을 보유하는 경우 ?연사자 구문은 null 결과를 반환합니다.

val p: Person? = Person(Country(null))

val res = p?.country?.code

assertNull(res)

4.1 let() 메서드

null을 허용하지 않는 값을 보유할 때만 연산을 하려면 let 연산자를 사용할 수 있습니다.

아래와같이 변수 목록이 있고 해당 목록에 null 값 도 있다고 가정해 보겠습니다 .

val firstName = "Tom"
val secondName = "Michael"
val names:List<String?> = listOf(firstName, null, secondName)복사

다음으로 let 함수 를 사용하여 이름 목록 의 null이 아닌 모든 요소에 대해 작업을 실행할 수 있습니다.

var res = listOf<String?>()
for (item in names) {
    item?.let { res = res.plus(it) }
}
assertEquals(2, res.size)
assertTrue { res.contains(firstName) }
assertTrue { res.contains(secondName) }복사

4.2. also() 메서드

예를 들어 null을 허용하지 않는 모든 값에 로깅과 같이 일부 추가 작업을 적용 하려는 경우 also() 메서드를 사용하고 let()과 연결할 수 있습니다.

var res = listOf<String?>()
for (item in names) {
    item?.let { res = res.plus(it); it }
  ?.also{it -> println("non nullable value: $it")}
}

null이 아닌 모든 요소를 출력합니다:

non nullable value: Tom
non nullable value: Michael

4.3. run() 메소드

Kotlin에는 nullable 참조에서 일부 작업을 실행 하는 run() 메서드가 있습니다. let() 과 매우 유사 하지만 함수 본문 내에서 Run() 메서드 는 함수 매개 변수 it대신 대신 this가 item역할을 합니다.

var res = listOf<String?>()
for (item in names) {
    item?.run{res = res.plus(this)}
}

5. 엘비스 연산자

아래와같이 변수가 있을 때 변수가 null 이 할당되는경우 작업에서 기본값을 반환하려고 합니다 . 이런작업을 하려면 elvis ( ?: ) 연산자를 사용할 수 있습니다. 이는 Java Optional 클래스 의 orElse/orElseGet 과 동일합니다.

val value:String? = null

val res = value?.length ?: -1

assertEquals(res, -1)

참조 가 null을 허용하지 않는 값을 보유하는 경우 -1 이 변수에 할당됩니다.

val value:String? = "name"
val res = value?.length ?: -1
assertEquals(res, 4)

6. Nullable Unsafe Get

또한 Kotlin에는 부재 논리를 명시적으로 처리하지 않고 null 허용 필드의 값을 가져오는 안전하지 않은 연산자가 있지만 매우 신중하게 사용해야 합니다.

이중 느낌표 연산자( !! )는 null 허용 변수에서 값을 가져오고 null 을 가지고 있는 변수인경우 NullPointerException 을 발생 시킵니다. 이것은 Optional.get() 작업과 동일합니다.

var b:String? = "value"
b = null
assertFailsWith<NullPointerException> {
    b!!
}

nullable 참조가 null을 허용하지 않는 값을 보유하는 경우 해당 값은 정상처리됩니다.

val b:String? = "value"
assertEquals(b!!.length, 5)

7. List에서 Null 값 필터링

Kotlin 의 List에서 null을 허용하지 않는 값만 반환 하는 유틸리티 메서드 filterNotNull() 이 있습니다.

val list:List<String?> = listOf("a", null, "b")

val res = list.filterNotNull()

assertEquals(res.size, 2)
assertTrue { res.contains("a") }
assertTrue { res.contains("b") }

위 기능을 이용하면 손쉽게 NotNull 값들만 Filter할 수 있습니다.

반응형