kotlinlang.org 내가 보려고 정리 - Null safety
Null safety
코틀린에서 null 값을 가질 수 있다.
null 값으로 발생할 수 있는 이슈들을 막기 위해 null safety가 있다.
런타임(실행 시간)보다는 컴파일 타임에 Null safety가 null 값으로 인해 생길 수 있는 문제들을 탐지한다.
-null 값을 허용할 때 명시할 수 있게 한다.
-null 값을 확인한다.
-null 값을 가지고 있을 property나 function에 safe call을 사용할 수 있게 한다.
-null 값이 탐지되었을 때 취할 행동을 선언할 수 있게 한다.
Nullable types
nullable type: null 값을 가질 수 있는 타입.
기본적으로는 null 값을 허용하지 않지만, 타입 선언 뒤에 ?을 붙여 nullable type을 선언할 수 있다.
fun main() {
var neverNull: String = "This can't be null"
neverNull = null // compiler error
// String 뒤에 ?을 붙여 nullable type으로 만듦.
var nullable: String? = "You can keep a null here"
nullable = null // 에러 안남.
// 타입 명시를 하지 않을 때, 기본적으로 null 값을 가질 수 없음.
var inferredNonNull = "The compiler assumes non-null"
inferredNonNull = null // 따라서 에러 발생.
fun strLength(notNull: String): Int { // 이 함수는 인자로 nullabe type을 받을 수 없음.
return notNull.length //반환 값도 마찬가지.
}
println(strLength(neverNull)) // 18.. nerverNull은 String 이므로.
println(strLength(nullable)) // 에러 발생.. nullable은 String?이므로.
}
Check for null values
conditional expression으로 null 값 존재 여부를 확인할 수 있다.
fun describeString(maybeString: String?): String {
if (maybeString != null && maybeString.length > 0) {
//maybeString이 null 값을 가지지 않고, 길이가 0보다 클 때
// maybeString.length > 0 && maybeString != null 이렇게 조건문 순서 바꾸면 에러 발생.
return "String of length ${maybeString.length}"
} else {//maybeString이 null 값을 갖거나, 길이가 0 이하일 때
return "Empty or null string"
}
}
fun main() {
var nullString: String? = null
println(describeString(nullString))
// Empty or null string
}
Use safe calls
null 값을 가질 수 있는 object의 property에 안전하게 접근하기 위해 safe call operator(?.)을 사용한다.
object의 property가 null일 때 null 반환.
fun lengthString(maybeString: String?): Int? = maybeString?.length
// maybeString이 null이면 null을 반환하고, 아니면 maybeString.length를 반환한다.
fun main() {
var nullString: String? = null
println(lengthString(nullString))
// null
var myString: String? = "Me!"
println(lengthString(myString))
//3
}
safe calls은 연속될 수 있기 때문에 만약 object의 property가 null 값을 포함하는 경우에 에러 없이 null을 반환한다.
person.company?.address?.country
//person.company와 person.company.address가 nullable type일 것이다.
safe call 연산자는 extension이나 member function을 호출할 때에도 사용할 수 있다.
이 경우에 함수를 호출하기 전에 null check이 일어난다.
null 값이 발견된 경우 함수는 호출되지 않고 null을 반환한다.
fun main() {
var nullString: String? = null
println(nullString?.uppercase())
// nullString이 null 값을 가지기 때문에 uppercase()를 호출하지 않고 null을 반환한다.
}
Use Elvis operator
Elvis operator(?:)를 사용하여 null 값이 탐지되었을 때 기본 값을 반환하게 할 수 있다.
null 값 확인 대상 ?: null 값이 발견되었을 때 반환할 값
fun main() {
var nullString: String? = null
//nullString이 null 값을 가지기 때문에 nullString?.length는 null 값을 가지게 된다.
// null ?: 0 으로 볼 수 있는데, ?: 왼쪽이 null 값이기 때문에 기본값인 0을 반환한다.
println(nullString?.length ?: 0)
// 0
}