F.R.I.D.A.Y.

Kotlin: 06 세이프콜과 non-null 단정 본문

DEV/Kotlin

Kotlin: 06 세이프콜과 non-null 단정

F.R.I.D.A.Y. 2020. 3. 29. 22:44
반응형

 원래라면 04 자료형의 비교와 변환에서 함께 다루어야 했습니다. 삼중 등호를 이해하려면 말이죠. 그러나 처음 접하는 사람들은 이를 난해하게 생각할 수 있습니다. 그래서 조금 뒤인 이번 06번으로 미루었습니다.


세이프콜

 값이 존재하지 않는 상태의 변수를 호출하면 컴파일러는 오류를 토해내고 컴파일을 중단합니다.

초기화가 필요하다고 하면서 컴파일을 중단함

 위와 같이 null값[# 이처럼 값이 존재하지 않는 상태를 프로그램에서는 null이라고 명명했습니다]을 가진 변수의 호출로 발생하는 NullPointerException문제(NPE 문제)는 많은 개발자들을 골머리 앓게 합니다. 그래서 코틀린은 이 문제를 해결할 수 있도록 세이프콜이란 문법이 존재합니다.

변수 선언

 세이프콜을 사용할 때는 세이프콜이 가능한 변수를 선언해야 합니다. 세이프콜이 가능한 변수 선언은 변수를 선언할 때 자료형을 작성한 뒤, 바로 뒤에 '?' 기호를 넣어서 선언합니다.

var num1:String  // null 비허용 변수
var num2:String? // null 허용 변수, safe-call 사용 가능

 이렇게 선언하고 나면 세이프콜, 혹은 이후에 나올 non-null 단정 기호만을 이용할 수 있습니다.

세이프콜, non-null 단정 기호 모두 사용하지 않아 컴파일 오류가 발생했다

세이프콜 사용

 세이프콜 또한, 선언과 비슷하게 사용합니다.

var str:String?
str = "Hello world!"

println("\"$str\" length is ${str?.length}")

 객체의 메서드[# 여기에서는 str?.length에서 str이 객체, length가 str의 메서드가 됩니다.]를 호출할 때 멤버 연산자[# .] 앞에 "?"를 붙여 세이프콜을 할 수 있습니다.

 이렇게 되면 str 변수의 값이 null이었을 때 기존에는 오류를 나타내던 것이 이제 null을 출력하고 다음 작업으로 넘어갑니다.

값은 null, 값이 존재하지 않으므로 메서드가 호출되지 않고 null을 반환한다.

 세이프콜을 사용하면 NPE 문제를 해결할 수 있으므로 조금은 편해집니다. 굳이 null 체크 부분을 넣지 않아도 되니까요. 만일 세이프콜이 없었다면 이렇게 작성해야 했을 겁니다.

// 가장 기본적인 null값 검사
var str:String? = null
if(str != null){
	println("\"$str\" length is ${str?.length}")
}

 많은 검사가 이루어질수록 들여 쓰기가 많아져 보기가 힘들 것입니다. 게다가 이렇게 연산을 거치면 값이 존재할 때만 출력이 이루어지므로 null 상태의 출력도 함께 작성해주어야 하죠.

엘비스 연산자(Elvis operator)

 그래서 값이 null일 때를 대비한 엘비스 연산자가 존재합니다. 엘비스 연산자는 값이 존재할 때와 존재하지 않을 때로 구분 지어 값을 반환하도록 할 수 있습니다.

구조

 엘비스 연산자( ?: )는 아래와 같은 구조를 가집니다.

str?.length ?: -1

 구조 설명을 하면, str이라는 문자열 변수에 값이 존재할 때는 문자열의 길이를 반환하지만, 그렇지 않을 때는 null 대신 -1을 반환합니다.

 모습이 C 언어의 삼항 연산자와 비슷합니다. 그러나 주의할 점은 엘비스 연산자는 물음표(?)와 콜론(:) 문자 사이에 아무것도 들어가지 않는다는 점입니다.

as에서의 사용

 지난 시간 04 자료의 비교와 변환에서 as 키워드를 잠시 배웠습니다. as는 변환될 수 없는 경우 오류를 토해낸다고 했는데요, 만일 오류를 뱉어내지 않게 하려면 as 뒤에 세이프콜을 위한 "?" 문자를 넣어주면 됩니다.

var str:String? = null

if(str as? Int) println("$str")
// 물음표 기호를 통해 예외 발생을 처리함

non-null 단정

 값이 존재하지 않을 수 있지만 특정 구역에서는 값이 절대 null일 수 없다고 확신할 수도 있습니다. 그렇게 되면 굳이 값이 null인지 체크하는 과정을 거치지 않아도 됩니다. 이때 우리는 non-null 단정 기호 "!!"를 사용할 수 있습니다.

non-null 단정 기호 사용하기

 사용 방법은 다음과 같습니다. 우리가 세이프콜을 위해 멤버 연산자 앞에 "?" 문자를 붙인 것처럼, non-null 단정 기호 "!!"를 붙여주면 됩니다.

var str:String? = null

println("${str!!.length}")

 위 코드는 str 변수가 null 값을 가질 수 있도록 설계되어 있지만, 변수를 사용하는 데에서 non-null 단정 기호를 사용했기 때문에 실행 시 오류를 출력합니다.

NullPointerException 오류를 출력하는 모습


 이 정도면 코틀린의 기초는 알아두었다고 봐도 되겠네요. 다음 시간에는 함수와 관련된 포스트를 진행합니다.

Next.

 

Kotlin: 07 함수

이번 시간에는 함수에 대해 알아봅니다. 함수를 사용하는 순간부터 프로그램 작성 방식에 대한 패러다임이 바뀔 겁니다. 꼭 알고 넘어가길 바랍니다. 함수 우리는 살면서 많은 일을 합니다. 밥을 먹을 수도 있고,..

pang2h.tistory.com

# index

728x90
반응형

'DEV > Kotlin' 카테고리의 다른 글

Kotlin: 08 분기 제어-if  (0) 2020.04.01
Kotlin: 07 함수  (0) 2020.03.31
Kotlin: 05 연산자  (0) 2020.03.28
Kotlin: 04 자료의 비교와 변환  (0) 2020.03.27
Kotlin: 03 출력하기  (0) 2020.03.24
Comments