상상하라 그리고 현실로 만들어라.

상상하는 모든 것이 미래다.

Kotlin과 Android/Kotlin

코틀린 Null 허용성(Null Safety)

월터제이(Walter J) 2020. 10. 19. 09:00

안녕하세요, 반갑습니다!

 

개발을 하다보면 값이 없거나 'NullPointerException' 오류 메시지를 만날때가 있습니다.

코드가 짧으면 금방 찾을 수 있지만, 조금 길어지고 참조해야할 변수들이 많아지기 시작하면 휴...

 

그래서 우리 개발자들은 이 null 값에 대한 처리를 안할 수가 없습니다.

신경안쓰면 프로그램 또는 앱이 멈춰 버리는 일이 발생할 수도 있으니까요.

 

코틀린은 Null에 대한 처리에 꽤 많은 공을 들인 언어입니다.

늦은 초기화(lateinit, lazy), 안전 호출(?.), 엘비스 연산자(?:) 등에서 확인 할 수가 있죠.

 

먼저 초기화 및 null 허용을 안해준 코드를 작성하고 실행을 하면,

var todayNum:Int		//초기화 없이 변수 선언
//var todayNum:Int = null	//오류 발생, null 부분에 빨간줄이 생김

(사실 초기화 안된 변수를 사용하려 하면 바로 빨간줄이 생깁니다^^)

이렇게 초기화를 반드시 해야한다며 오류를...

네, 역시 null 을 허용하지 않습니다.

 

 

오늘의 포스팅

null 에 대한 안정적인 처리!

Null 허용성(Null Safety)

 

 

물론 위 방법처럼 선언 후 바로 밑에서 초기화를 해주면 문제는 없습니다.

하지만~ Null 허용성(Null Safety)에 대한 포스팅이니까요^^.

 

방법은 간단합니다. 변수를 선언할 때 자료형 타입뒤에 물음표( ? ) 만 붙여주면 됩니다.

var todayNum:Int? = null	//위와 달리 빨간줄이 사라짐

타입 뒤에 물음표(?) 만 붙여주면 null 초기화가 가능합니다.

 

 

이제 이렇게 선언된 변수를 사용해 볼까요?

 

1. 안전 호출 연산자

첫 번째로 안전 호출 연산자( ?. ) 를 사용해서 변수를 사용할 수 있습니다.

이 연산자는 null이 아닌 경우에만 값을 반환 합니다. 만약 null 값이면 null 을 반환하는 것이죠.

 

이 연산자로 null 체크를 기존의 자바보다 훨씬 간단하게 코드를 작성할 수 있게 됩니다.

기존의 자바였다면,

Long idx = arguments.getLong("IDX")//null을 확인하지 않고 일단 getLong()을 호출함

if (idx != null) {
	...
}

이렇게 null 체크를 해야겠죠?

 

하지만, 코틀린의 이 안전 호출 연산자로 인해서 아래와 같이 간단히 사용할 수 있습니다.

val idx = arguments?.getLong("IDX")	//arguments 가 null 이면 getLong() 을 호출하지 않음

즉, 안전 호출 연산자( ?. ) 는 값에 따라 뒤에 나오는 속성 또는 명령어를 처리하기 위해 사용하는 것입니다.

 

 

2. 엘비스 연산자

두 번째는 엘비스 연산자( ?: ) 입니다.

안전 호출 연산자( ?. )를 써서 null 이 아닐 때만 호출을 할 수도 있지만, null 대신 기본 값으로 출력할 수도 있습니다.

val idx = arguments?.getLong("IDX") ?: 0 //null 일 경우 null 대신 0 이 됨

print("idx 는 ${idx} 입니다." ) // "idx 는 0 입니다" 로 출력됨

 

두 방법 외에도 값을 가져올 수 있는 방법이 있습니다.

바로 단언 연산자( !! ) 를 사용해서 값을 보증 하는 것입니다.

var number_1 = 10
var number_2:Int? = null;
        
var sum = number_1 + number_2!!	//단언 연산자(!!) 를 써서 오류가 사라짐
print("합계 $sum")

위 코드에서 단언 연산자( !! ) 를 쓰지 않는다면, 바로 빨간줄이 쫙! 생깁니다.

하지만, 단언 연산자( !! )를 쓰므로써 오류는 사라집니다.

 

말 그대로 값이 "null 임을 보증할테니 그냥 써!" 라고 하는 것이죠.

뭐.. 그래도 저런 식이면 바로 'NullPointerExceptino' 오류를 바로 만나긴 합니다.

그러므로 이 방법은 가급적 지양해야 하는 방법입니다.

코드 스멜 (code smell) 이라고 잠재적으로 문제가 있는 코드를 말합니다.

위 오류처럼 막상 까보니 null 일 수 있고, 문제가 생길 수 있기 때문이죠.

 

 

One more thing!

· 함수에도 null 허용하기

함수의 파라미터와 반환 값 또한 null 허용성(Null Safety) 을 사용할 수 있습니다.

fun getStrLength(str: String?) : Int? {
    var result:Int? = str?.length	//str이 null이면 length를 호출하지 않음
    return result
}

str 이 null 이면 length 를 호출하지 않으니, result 는 null 이 됩니다.

 

 

 

기존 자바에 비해서 무조건 초기화를 해야하는 번거로움이 있긴하지만,

null 에 대한 처리를 변수 선언단계부터 하기 때문에 안정성은 더 높아졌다고 할 수 있을 것 같습니다.

 

감사합니다!

반응형