티스토리 뷰
728x90
- 널이 될 수 있는 타입과 널이 될 수 없는 타입을 구분한다.
- → 널 발생 여부를 컴파일 시점으로 옮겨주기 때문에 NullPointerException 예외를 방지할 수 있다.
- 기본적으로 코틀린의 모든 타입은 널이 될 수 없는 타입이다. → 널에 대한 검사를 추가로 수행할 필요가 없다.
- 널이 될 수 있는 타입(nullable type)
- 타입 뒤에 ?를 붙여 지정할 수 있다.
- ex) val s: String? = "abc"
- 널이 될 수 없는 타입(non-nullable type)의 상위 타입이므로, nullable type에 non-nullable type의 값을 대입할 수 있다.
fun isLetterString(s: String?): Boolean {
if(s.isEmpty()) return false // error
for(ch in s) { // error
if (!ch.isLetter()) return false
}
return true
}
- non-nullable type의 프로퍼티나 메서드를 제공하지 않는다. → 확장 메커니즘 활용. (추후에 공부)
- 위 함수의 파라미터 타입이 String?이기 때문에 String이 제공하는 isEmpty(), iterator() 메서드를 사용하면 컴파일 오류가 발생한다.
2. 스마트 캐스트
fun isLetterString(s: String?): Boolean {
if(s == null) return false
if(s.isEmpty()) return false
for(ch in s) {
if (!ch.isLetter()) return false
}
return true
}
- 널 검사를 수행하면, 컴파일러가 그 아래의 문장부터는 확실히 널이 아니라는 사실을 알고 String?에서 String으로 타입 변환을 한다.
- when의 조건이나 && || 연산에서도 스마트 캐스트가 동작한다.
- 스마트 캐스트 조건
- 불변 변수는 항상 스마트 캐스트를 적용할 수 있다.
- 가변 변수는 널 검사 이후 값이 변경되는 경우 스마트 캐스트가 동작하지 않는다.
- 클래스의 가변 프로퍼티는 스마트 캐스트를 적용할 수 없다.
3. 널 아님 단언 연산자 (not-null assertion)
- nullable type의 변수 뒤에 !! 를 붙여 사용한다.
- !!이 붙은 변수의 타입은 non-nullable type으로 변환되고, 변수에 널 값이 들어있다면 NullPointerException 예외를 던진다.
4. 안전한 호출 연산자 (safe call)
fun main() {
val s1: String? = null
val s2: String? = "abc"
println(s1?.length) // null
println(s2?.length) // 3
}
- 안전한 호출 연산자(?.)를 사용하면 nullable type이어도 non-nullable type이 제공하는 메서드를 사용할 수 있다.
- 함수를 호출한 타입이 널이 아닌 경우 일반적인 함수 호출처럼 작동하고, 널인 경우 함수를 호출하지 않고 바로 널을 반환한다.
- 연산자를 사용하여 호출한 함수의 반환값은 항상 nullable type이다.
5. 엘비스 연산자
fun main() {
val i: Int? = null
val j: Int? = 34
println(i ?: 10) // 10
println(j ?: 10) // 34
}
- 엘비스 연산자(?:)를 통해 널을 대신할 디폴트 값을 지정할 수 있다.
- 왼쪽 피연산자가 널일 경우 오른쪽 피연산자의 값이고, 널이 아닐 경우 그대로 왼쪽 피연산자의 값이다.
728x90
'app > kotlin' 카테고리의 다른 글
[kotlin/코틀린] 객체 (0) | 2023.06.22 |
---|---|
[kotlin/코틀린] 프로퍼티 (0) | 2023.06.22 |
[kotlin/코틀린] 클래스 정의하기 (0) | 2023.06.22 |
[kotlin/코틀린] 기초 문법 (문자열, 배열, 함수) (0) | 2023.06.22 |
[kotlin/코틀린] 기초 문법 (변수, 타입) (0) | 2023.06.22 |