본문으로 바로가기
반응형

Photo by unsplash

kotlin이 v1.9쯤 오니까 갑자기 버전이 훅!! 올라간것같은 기분이 드네요.

역시나 안정화 되고 출시를 앞둔 K2 compiler가 Beta로 올라왔다는 말로 시작을 장식합니다..만!!

아직은 여러 제약조건들이 존재하는것 같아서 일단 이 얘기는 제외 하려고 합니다. 정확하게는 KSP와 Compose의 지원이 아직은 미흡하고 추후 2.0 정식 출시시 통합된다고 하니, 그때를 기다려 봐야 겠습니다. 

사실 빌드 속도가 얼마나 빨라질지 두근두근 합니다만..

지금은 적용해서 돌면 다행, 안돌면 그만인 상황이라, K2 Compiler 얘기는 제외하고 언어적으로 바뀐 부분이 무엇인지만 간략하게 정리합니다.

K2 compiler 적용 관련된 부분을 보고 싶으시다면 하기 references에 링크를 타고 진입 하시면 됩니다.[1]


language 부분에서 크게 세가지 정도를 언급하고 있는데, 두개는 이미 1.8.20에서 나왔던 기능의 안정화 처리이고, 나머지 하나만 새롭네요.

Stable replacement of the enum class vlaues function

1.8.20에서 experimental로 추가되었던 enum class의 entries 속성이 stable로 변경되었습니다. 기존 values()를 대체하는 속성으로 일단 가지고 있는 원소를 모두 list 형태로 반환해 주기 때문에 성능이나 활용면에서 훨신 편해 졌습니다. (list의 api를 편하게 다 사용할 수 있습니다.)

참고로 values()는 array를 반환합니다.

enum class IceCream(val price: Int) {
    GRAPE_FLAVOR(500),
    APPLE_FLAVOR(400),
    ORANGE_FLAVOR(300),
    PEAR_FLAVOR(600)
}

fun availableIceCream(pocketMoney: Int): List<IceCream> {
    return IceCream.entries.filter { it.price <= pocketMoney}
}

 

Stable data objects for symmetry with data classes

data object 역시 kotlin 1.8.20에서 experimental로 추가 되었던 기능인데, stable로 변경되었습니다. data object는 기본적으로 일반 object와 동일하지만 내부적으로 toString(), euquals(),hasCode()를 구현하고 있습니다.

사실 기본 kotlin의 object를 대체하는 개념은 아닙니다만 (여전히 object는 유효합니다.) sealed classssealed interface에서 data class와 같이 사용시 대칭되는 개념으로 사용하기에 유리합니다.

sealed interface ServerApiResult

data class ExceptionResult(val error: Throwable): ServerApiResult
data class ErrorStateResult(val status: Int, val message: String): ServerApiResult
object Success: ServerApiResult
data object Processing: ServerApiResult

fun printServerApiResult(result: ServerApiResult) {
    when (result) {
        is ErrorStateResult -> LogError("Test") {"Error - State:$result"}
        is ExceptionResult -> LogError("Test") {"Exception: $result"}
        Processing -> LogDebug("Test") {"Processing: $result"}
        Success -> LogDebug("Test") {"Success: $result"}
    }
}

 

위 예제에서 Success는 일반 object로, Processingdata object로 선언했습니다. 이때 아래와 같이 객체 자체의 로그를 찍어보면 아래와 같습니다.

fun main() {
    printServerApiResult(ExceptionResult(NullPointerException()))
    printServerApiResult(ErrorStateResult(500, "wow!! error"))
    printServerApiResult(Processing)
    printServerApiResult(Success)
}

Processingdata object이므로 toString()이 override 되어있어 예쁘게 로그가 남지만, Success의 경우 object이므로 메모리 주소와 함께 전체 package 패스가 다 남습니다. 

data object가 없었더라면 아래와 같이 override를 했어야 겠죠?

object Success: ServerApiResult {
    override fun toString(): String {
        return "Success"
    }
}

 

Support for secondary constructors with bodies in inline value classes

value class는 한개의 param만 선언할수 있었습니다. v1.9.0 부터는 constructor를 사용할 수 있고, 따라서 두개 이상의 param를 받을 수 있습니다.

@JvmInline
value class Car(val name: String) {
    constructor(name: String, manufacturer: String): this("$name | $manufacturer")
}

참고로 init {..} 역시 v1.4.30 부터 value class에서 사용 가능하도록 변경 되었습니다. value class의 개념은 하기 링크에서 확인 가능합니다.[3]

 

 

References

[1] https://kotlinlang.org/docs/whatsnew19.html#compatibility-of-the-kapt-compiler-plugin-with-the-k2-compiler

[2] https://kotlinlang.org/docs/whatsnew19.html#language

[3] 2022.07.06 - [개발이야기/Kotlin] - [Kotlin] New features by v1.6.0~v1.7.0 - exhaustive when, builder inference, parallel compile, K2 compiler and etc.

반응형