본문 바로가기
개발&프로그래밍

[kotlin] 타입 체크와 캐스팅

by 재아군 2024. 8. 11.

Kotlin의 타입 체크와 캐스팅

Kotlin에서 타입 체크와 캐스팅은 객체 지향 프로그래밍의 핵심 기능입니다. 이 가이드에서는 Kotlin의 타입 체크와 캐스팅 기능을 모든 코드 예제와 함께 상세히 살펴보겠습니다.

 

아래 글은 kotlinlang.org의 공식 홈페이지의 문서를 참고하였습니다.

 

 

 


 

is와 !is 연산자 (is and !is operators)

is!is 연산자는 객체의 타입을 런타임에 확인할 수 있게 해줍니다.

if (obj is String) {
    print(obj.length)
}

if (obj !is String) { // !(obj is String)과 동일
    print("문자열이 아닙니다")
} else {
    print(obj.length)
}

이 연산자들은 특히 다형성을 활용할 때 유용합니다. 예를 들어, 여러 타입의 객체를 처리해야 하는 함수에서 각 객체의 타입에 따라 다른 동작을 수행할 수 있습니다.

 

 

스마트 캐스트 (Smart casts)

Kotlin의 스마트 캐스트 기능은 명시적인 캐스팅 없이도 컴파일러가 자동으로 타입을 추론하고 캐스팅해주는 강력한 기능입니다.

fun demo(x: Any) {
    if (x is String) {
        print(x.length) // x가 자동으로 String으로 캐스트됨
    }
}

 

 

컴파일러는 음수 체크가 반환으로 이어질 경우에도 캐스트가 안전하다는 것을 알 만큼 똑똑합니다:

if (x !is String) return

print(x.length) // x가 자동으로 String으로 캐스트됨

 

스마트 캐스트는 코드를 더 간결하고 안전하게 만들어줍니다. 특히 타입 체크 후 해당 타입의 멤버에 접근할 때 매우 유용합니다.

 

 

제어 흐름 (Control flow)

스마트 캐스트는 if, when, while 등 다양한 제어 흐름 구조에서 작동합니다:

when (x) {
    is Int -> print(x + 1)
    is String -> print(x.length + 1)
    is IntArray -> print(x.sum())
}

 

 

이는 복잡한 타입 체크와 캐스팅 로직을 간결하게 표현할 수 있게 해줍니다.

boolean 변수를 사용하여 조건을 표현할 수도 있습니다:

class Cat {
    fun purr() {
        println("Purr purr")
    }
}

fun petAnimal(animal: Any) {
    val isCat = animal is Cat
    if (isCat) {
        // 컴파일러는 isCat에 대한 정보를 알고 있으므로,
        // animal이 Cat 타입으로 스마트 캐스트되었음을 알 수 있습니다.
        // 따라서 purr() 함수를 호출할 수 있습니다.
        animal.purr()
    }
}

fun main(){
    val kitty = Cat()
    petAnimal(kitty)
    // 출력: Purr purr
}

 

 

논리 연산자 (Logical operators)

스마트 캐스트는 &&|| 연산자와 함께 사용될 때도 작동합니다:

// x는 || 연산자의 오른쪽에서 자동으로 String으로 캐스트됨
if (x !is String || x.length == 0) return

// x는 && 연산자의 오른쪽에서 자동으로 String으로 캐스트됨
if (x is String && x.length > 0) {
    print(x.length) // x가 자동으로 String으로 캐스트됨
}

 

 

객체에 대한 타입 체크를 || 연산자로 결합하면, 가장 가까운 공통 상위 타입으로 스마트 캐스트됩니다:

interface Status {
    fun signal() {}
}

interface Ok : Status
interface Postponed : Status
interface Declined : Status

fun signalCheck(signalStatus: Any) {
    if (signalStatus is Postponed || signalStatus is Declined) {
        // signalStatus가 공통 상위 타입 Status로 스마트 캐스트됨
        signalStatus.signal()
    }
}

 

 

인라인 함수 (Inline functions)

인라인 함수 내에서 캡처된 변수에 대해서도 스마트 캐스트가 가능합니다:

interface Processor {
    fun process()
}

inline fun inlineAction(f: () -> Unit) = f()

fun nextProcessor(): Processor? = null

fun runProcessor(): Processor? {
    var processor: Processor? = null
    inlineAction {
        // 컴파일러는 processor가 지역 변수이고 inlineAction()이
        // 인라인 함수이므로 processor에 대한 참조가 유출될 수 없음을 알고 있습니다.
        // 따라서 processor를 안전하게 스마트 캐스트할 수 있습니다.

        // processor가 null이 아니면 스마트 캐스트됩니다.
        if (processor != null) {
            // 컴파일러는 processor가 null이 아님을 알고 있으므로
            // 안전 호출이 필요하지 않습니다.
            processor.process()
        }

        processor = nextProcessor()
    }

    return processor
}

이 기능은 성능 최적화와 함께 타입 안전성을 제공합니다.

 

 

예외 처리 (Exception handling)

스마트 캐스트 정보는 catchfinally 블록으로도 전달됩니다:

fun testString() {
    var stringInput: String? = null
    // stringInput이 String 타입으로 스마트 캐스트됨
    stringInput = ""
    try {
        // 컴파일러는 stringInput이 null이 아님을 알고 있음
        println(stringInput.length)
        // 0

        // 컴파일러는 stringInput에 대한 이전 스마트 캐스트 정보를 거부합니다.
        // 이제 stringInput은 String? 타입입니다.
        stringInput = null

        // 예외 발생
        if (2 > 1) throw Exception()
        stringInput = ""
    } catch (exception: Exception) {
        // 컴파일러는 stringInput이 null일 수 있음을 알고 있으므로
        // stringInput은 nullable 상태를 유지합니다.
        println(stringInput?.length)
        // null
    }
}

이는 예외 처리 시 nullable 타입을 더 안전하게 다룰 수 있게 해줍니다.

 

 

"안전하지 않은" 캐스트 연산자 ("Unsafe" cast operator)

명시적 캐스팅이 필요할 때는 as 연산자를 사용합니다:

val x: String = y as String

 

 

하지만 이 방법은 캐스팅이 실패할 경우 예외를 발생시키므로 주의가 필요합니다.

y가 null인 경우에도 예외가 발생합니다. null 값을 허용하려면 nullable 타입으로 캐스트해야 합니다:

val x: String? = y as String?

 

"안전한" (nullable) 캐스트 연산자 ("Safe" (nullable) cast operator)

예외를 피하기 위해 as? 연산자를 사용할 수 있습니다:

val x: String? = y as? String

이 방법은 캐스팅 실패 시 null을 반환하므로, null 안전성을 유지하면서 캐스팅을 수행할 수 있습니다.

 

 

Kotlin의 타입 체크와 캐스팅 기능은 코드의 안전성과 표현력을 크게 향상시킵니다. 스마트 캐스트를 통해 대부분의 경우 명시적인 캐스팅 없이도 타입 안전성을 보장할 수 있으며, 필요한 경우 asas? 연산자를 사용하여 명시적 캐스팅을 수행할 수 있습니다.

이러한 기능들을 적절히 활용하면 더 안전하고 읽기 쉬운 Kotlin 코드를 작성할 수 있습니다. 특히 다양한 타입의 객체를 다루는 복잡한 로직에서 이러한 기능들이 큰 도움이 될 것입니다.

Kotlin 개발자라면 이러한 타입 체크와 캐스팅 기능을 잘 이해하고 적절히 사용하는 것이 중요합니다. 이를 통해 더 견고하고 유지보수가 용이한 코드를 작성할 수 있을 것입니다.

 

 

이 블로그의 다른글 :

2024.08.10 - [개발&프로그래밍] - [Kotlin] 숫자 타입과 연산 가이드

 

[Kotlin] 숫자 타입과 연산 가이드

Kotlin의 숫자 타입과 연산 가이드Kotlin에서 숫자를 다루는 방법과 관련된 다양한 개념을 살펴봅니다.  정수 타입 (Integer types)Kotlin은 숫자를 표현하기 위한 내장 타입 세트를 제공합니다. 정수의

observerlife.tistory.com

 

 

2024.08.10 - [개발&프로그래밍] - [kotlin] 코딩 컨벤션 - lambdas, Trailing commas

 

[kotlin] 코딩 컨벤션 - lambdas, Trailing commas

Kotlin 코딩 컨벤션 가이드Kotlin을 사용하여 더 깔끔하고 일관된 코드를 작성하기 위한 고급 코딩 컨벤션을 소개합니다.아래글은 공식 홈페이지를 참고하였습니다.https://kotlinlang.org/docs/coding-convent

observerlife.tistory.com

 

 

 

2024.08.09 - [개발&프로그래밍] - [kotlin] 코딩 컨벤션 (coding conventions)

 

[kotlin] 코딩 컨벤션 (coding conventions)

Kotlin 코딩 컨벤션 가이드 Kotlin 프로그래밍 언어를 사용할 때 따라야 할 코딩 컨벤션에 대한 종합적인 가이드입니다.이 가이드라인을 따르면 코드의 일관성과 가독성을 높일 수 있습니다. 이

observerlife.tistory.com

 

 

 

2024.08.09 - [개발&프로그래밍] - [kotlin] 자주 사용되는 관용구(idiom) 모음

 

[kotlin] 자주 사용되는 관용구(idiom) 모음

이 글은 Kotlin 프로그래밍 언어에서 자주 사용되는 관용구(idiom)들의 모음입니다.각 관용구에 대한 설명과 예제 코드를 함께 설명합니다.공식 홈페이지 kotlinlang.org의 내용을 참고합

observerlife.tistory.com

 

 

2024.08.07 - [개발&프로그래밍] - [kotlin] 입문시 알아야 할 8가지 핵심 문법

 

[kotlin] 입문시 알아야 할 8가지 핵심 문법

Kotlin의 주요 문법 특징들을 간략히 정리한 것입니다.각 항목은 Kotlin의 간결하고 표현력 있는 코드 작성을 지원하는 특징들을 보여줍니다. 아래 문서는 kotlinlang.org 공식 홈페이지를 참조합니다.

observerlife.tistory.com

 

 

2024.08.07 - [개발&프로그래밍] - [kotlin] 입문시 알아야 할 7가지 핵심 문법

 

[kotlin] 입문시 알아야 할 7가지 핵심 문법

Kotlin의 기본적인 문법 요소들을 간략하게 설명하고 있습니다.각 항목은 Kotlin 프로그래밍의 기초를 이해하는 데 중요한 개념들을 포함하고 있습니다. 아래 문서는 kotlinlang.org 공식 홈페이지를

observerlife.tistory.com

 

 

 

 

#Kotlin
#타입체크
#캐스팅
#스마트캐스트
#안전한프로그래밍
#KotlinTips
#객체지향프로그래밍
#NullSafety
#KotlinDevelopment
#코틀린문법

 

 

 

 

댓글