본문 바로가기

Kotlin

코틀린, 코틀린답게 사용하기 - 5. Nullable Type

이번 포스팅에서는 코틀린의 가장 큰 장점 중 하나인 널이 될 수 있는 타입에 대하여 알아보겠습니다

 

1. Nullable Type, Non-Null Type

Kotlin in Action 6장 앞부분에서는 다음과 같이 소개합니다.

 

코틀린과 자바의 첫 번째이자 가장 중요한 차이는 코틀린 타입 시스템이 널이 될 수 있는 타입을 명시적으로 지원한다는 점이다.

자바에 익숙했던 제가 처음에 공부할 때는 이게 왜 중요한 차이인지 잘 모르겠고 그냥 그런갑다~ 했었는데..

 

공부를 하다가보니 머리속에서는 이렇게 남아있게 되었고 다시 돌아간다고 생각하면..🙀

 

자바에서는 같은 타입일지라도 코틀린에서는 널이 될 수 있는 타입과 될 수 없는 타입 두가지로 분류된다.
- Non-Null: 널이 될 수 없는 타입은 말 그대로 Null 이 들어오지 않으므로 따로 유효성 처리를 할 필요가없다.
- Nullable: 널이 될 수 있음이 코드상에 드러나기 때문에 적절한 null 처리를 하지 않으면 안된다.

이 Nullable Type 덕분에! 실행 시점에서 문제가 생겼던 Null이 컴파일 시점에서 처리를 할 수 있다는 것입니다.

즉, NullPointerException 으로 부터 해방을~~

 

유효성처리에 대하여 조금 더 살펴보자면,

자바코드에서는 null이 들어올 가능성이 있다면 다음과 같이 유효성처리를 해줘야하는데요,

 

if(Objects.isNull(string)) {
  string = ""
}

 

이러한 코드는 개발자의 마음은 편하게 해주지만 절대 null 이 아님은 보장할 수 없습니다. 적절한 위치에서 유효성체크를 하지않았다면요..

 

val string:String?
if (string == null) {
  string = ""
}

 

코틀린에서도 비슷하게 유효성처리를 할 수 있고, 이렇게 Nullable Type이 null 과 비교되었다면 이후로는 Non-Null Type 값처럼 사용할 수 있습니다. 즉 null 이 아님을 보장할 수 있고, 적절한 위치에서 유효성체크를 하지 않았다면 컴파일 시점에서 에러가 발생하여 문제자체를 차단할 수 있습니다.

 

 

2. Safe Calls & Elvis Operator

이러한 Nullable 타입시스템에 날개를 더해줄 강력한 기능을 코틀린이 제공해주고 있습니다. 덕분에 간결한 코드로 다를 수 있게 되었죠~

 

다시 Nullable 에 대하여 살펴보겠습니다!

 

 

String? 타입의 변수가 하나있고 그 값이 null 이라고 가정해보겠습니다. 

 

 

코틀린의 toUpperCase 함수는 코틀린의 String(Non-Null Type) 의 확장함수로 자바 String 타입의 toUpperCase() 를 호출하는 인라인 함수네요~ 이 함수를 이용하여 선언한 변수를 대문자로 바꾸려는 시도를 해보겠습니다.

 

 

Only safe (?.) or non null assserted (!!.) calls are allowed on a nullable receiver of type String?  이라는 메시지와 함께 컴파일 과정에서 에러가 발생합니다.

 

이는 Nullable 타입의 nullableString과 Non-Null 타입을 수신객체로하는 toUpperCase() 확장함수가 일치하지 않기때문입니다. 다시 말씀 드리지만 코틀린에서 두 타입은 다른 타입입니다.

 

확장함수의 수신객체타입을 Nullable 타입으로 변경하는 방법으로도 해결이 가능하겠지만~ 자바스타일로 접근해보겠습니다.

 

 

nullableString 의 유효성체크를 하고 가능한 경우에만 대문자로 바꿔주고 있는데, 매번 타입이 맞지 않을때마다 if 검사를 해야한다면 오히려 더 불편해질수도 있었겠네요..

 

2.1 Safe Calls

하지만 코틀린은 위의 코드를 다음과 같이 간결하게 다룰 수 있게 Safe Calls(?.) 연산자를 제공합니다.

 

 

여기서 주목해야할 점은 upperCaseString 의 타입이 String? 타입이라는 것입니다. toUpperCase() 가 Non-Null String 타입을 리턴하지만 Safe Calls 의 매커니즘으로 인해 String 이 아닌 String? 이 되겠네요.

 

2.2 Elvis Operator

그렇다면 uppercaseString 을 Null이 들어왔을 때 빈문자를 넣어서 Non-Null type 으로 바꾸는 방법은 없을까요? 

먼저 자바스타일로 한번..

 

 

자바와 다른점은 String 이 아닌 String? 로 선언하더라도 타입체크 후에는 Non-Null 타입처럼 쓸 수 있다는 것입니다만..

 

 

 

Safe Calls 와 Elvis Operator 를 통해 다음과 같이 간결하게 나타낼 수 있습니다.

 

지금 소개해드린 Safe Call 연산자와 Elvis 연산자뿐만아니라 코틀린에서는,

Safe Cast 연산자인 as? 와 Nullable 타입의 파라미터를 Non-Null 타입 파라미터로 보내줄 때 유용한 let 등으로 인하여 Nullable Type 을 더 쉽게 다룰 수 있습니다.

 

런타임시에 NullPointException 을 피하기위해 많은 제약들이 생겼지만 이러한 제약을 편리하게 지킬 수 있기 때문에 코틀린의 가장 큰 장점이라고 하는 것 같네요😎

 

 

 

 

 

 

More

  • Java의 @Nullable, @NotNull 과 비교
  • 플랫폼 타입
  • Non-null assertion 이 유용한 경우
  • let
  • Nullable Type 확장