Nullable 자료형 선언
코틀린에서 선언된 변수는 사용전에 반드시 값이 할당되어야 합니다.값이 할당되지 않은 변수를 사용하면 오류가 발생됩니다.
코틀린에서는 변수 선언시 값이 없음을 지정하여 이러한 예외를 방지할 수 있습니다.
값이 없는 상태를 null이라고 하며 변수선언시 '?'를 사용하여 선언할 수 있습니다.
val 변수명: 자료형?
var 변수명: 자료형?
var 변수명: 자료형?
일반적 변수 선언은 null 값을 허용하지 않습니다.
var obs="Kotlin"
obs=null
println(obs)
Null can not be a value of a non-null type String
var obs1:String?="Kotlin"
obs1=null
println(obs1)
null
obs=null
println(obs)
Null can not be a value of a non-null type String
var obs1:String?="Kotlin"
obs1=null
println(obs1)
null
Safe Call 또는 non-null(!!) 기호사용
null을 허용하는 변수에는 null을 허용하지 않은 속성이나 함수는 사용할 수 없습니다.사용할 경우 예외(NullPointerException, NPE)를 발생합니다.
다음 코드에서 사용된 속성
.length: 문장열 길이를 반환하는 속성
obs1.length
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
위의 경우 obs1은 null을 허용하는 변수(nullable variable)입니다.
반면에 속성.length는 null이 아닌 문자열 속성입니다. 그러므로 에러가 발생합니다.
이 과정은 전달하는 문자열이 nullable인지 아닌지를 먼저 검사한 후
null이 아니면 속성을 실행하고 아니면 null 값을 반환하도록 할 수 있습니다.
이러한 과정을 safe call 이라고 합니다.
println(obs1?.length)
null
null
safe call과는 반대로 non-null(!!)기호는 변수가 null 이 아님을 단정하여 null 검사를 무시합니다.
그러므로 컴파일이 진행되어도 예외를 발생합니다.
위 obs1.length는 컴파일이 진행되지 않은 것이지만 다음은 컴파일 진행후 에러가 발생한 것입니다.
println(obs1!!.length)
kotlin.KotlinNullPointerException
kotlin.KotlinNullPointerException
조건문으로 nullable 검사
다음과 같이 조건문을 사용하여 nullable의 여부를 검사할 수 있습니다.
fun main() {
var str1 : String? = "Hello Kotlin"
str1 = null
// 조건식을 통해 null 상태 검사
val len = if(str1 != null) str1.length else -1
println("str1: $str1 length: ${len}")
}
var str1 : String? = "Hello Kotlin"
str1 = null
// 조건식을 통해 null 상태 검사
val len = if(str1 != null) str1.length else -1
println("str1: $str1 length: ${len}")
}
위 코드에서는 str1에 이미 null이 할당되어 있기 때문에 len의 값으로 -1이 반환되었습니다.
엘비스(Elvis) 연산자 사용
세이프 콜(?.)과 엘비스 연산자(:)는 결합하여 사용하면 다음과 같습니다.
왼쪽 ?: 오른쪽 ;
null을 검사하여 null이면 왼쪽을 실행, 아니면 오른쪽 실행
null을 검사하여 null이면 왼쪽을 실행, 아니면 오른쪽 실행
fun main() {
var str1 : String? = "Hello Kotlin"
str1 = null
println("str1: $\$$str1 length: $\$${str1?.length ?: -1}") // 세이프 콜과 엘비스 연산자 활용
}
str1: null length: -1
var str1 : String? = "Hello Kotlin"
str1 = null
println("str1: $\$$str1 length: $\$${str1?.length ?: -1}") // 세이프 콜과 엘비스 연산자 활용
}
str1: null length: -1
fun main() {
var str1 : String? = "Hi, Kotlin"
str1 = null
println("str1: $\$$str1 length: $\$${str1?.length ?: -1}") // 세이프 콜과 엘비스 연산자 활용
}
str1: Hi, Kotlin length: 10
var str1 : String? = "Hi, Kotlin"
str1 = null
println("str1: $\$$str1 length: $\$${str1?.length ?: -1}") // 세이프 콜과 엘비스 연산자 활용
}
str1: Hi, Kotlin length: 10
위 코드 중 세이프콜과 엘비스 연산자는 다음과 같습니다.
str1?.length ?: -1 == if (str1 != null) str1.length else -1
댓글
댓글 쓰기