(Kotlin/코틀린) Kotlin 2.0 주요 변경사항 — K2 컴파일러


1. Kotlin 2.0이란?

2024년 5월 출시된 Kotlin 2.0은 K2 컴파일러를 기본 탑재한 첫 번째 안정 버전입니다.
K2는 기존 컴파일러(K1)를 완전히 새로 작성한 것으로, 성능과 안정성이 크게 향상됩니다.


2. K2 컴파일러 — 빌드 속도 향상

K2 컴파일러의 가장 큰 장점은 컴파일 속도입니다.

JetBrains 내부 벤치마크:
- 클린 빌드:  최대 2배 빠름
- 증분 빌드:  최대 94% 향상
- IntelliJ 플러그인 기준: 빌드 시간 60% 단축
// build.gradle.kts — K2 활성화 (2.0부터 기본값)
kotlin {
    compilerOptions {
        languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
    }
}

3. 스마트 캐스트 개선

K2의 새 분석기는 더 많은 상황에서 스마트 캐스트를 적용합니다.

local 변수 스마트 캐스트 (K1에서 불가)

// K1: 컴파일 에러 — local var는 람다에서 변경될 수 있다고 보수적으로 판단
// K2: 컴파일 성공 — 람다 호출 전후 변경 없음을 분석

class Animal {
    var isDog = false
    val canWalk get() = true
}

fun processAnimal(animal: Animal) {
    var isDog = animal.isDog
    // K1은 여기서 스마트 캐스트 거부
    // K2는 isDog이 이후 변경되지 않음을 파악해 스마트 캐스트 허용
    if (isDog) {
        println("강아지입니다")
    }
}

조건 내 논리 연산자 개선

interface Shape
class Circle(val radius: Double) : Shape
class Rectangle(val width: Double, val height: Double) : Shape

fun describeShape(shape: Shape?) {
    // K2: && 오른쪽에서도 스마트 캐스트 적용
    if (shape != null && shape is Circle) {
        println("원 반지름: ${shape.radius}")  // K2에서 스마트 캐스트 OK
    }
}

인라인 함수 이후 스마트 캐스트

fun process(value: String?) {
    requireNotNull(value)  // inline 함수
    // K2: value가 non-null임을 컴파일러가 인식
    println(value.length)  // K1에서는 ? 필요, K2에서는 불필요
}

4. when 표현식 — exhaustive 강화

sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error(val message: String) : Result<Nothing>()
}

fun handleResult(result: Result<String>) {
    // K2: when이 sealed class를 더 정확히 분석
    // else 없이도 exhaustive 판단이 개선됨
    when (result) {
        is Result.Success -> println(result.data)
        is Result.Error   -> println(result.message)
    }
}

5. data class copy() 가시성 변경 (예정)

// Kotlin 2.0 경고, 향후 버전에서 적용
data class User private constructor(val name: String, val age: Int)

// 기존: copy()는 항상 public → private 생성자를 우회 가능
// Kotlin 2.x: copy()가 생성자와 동일한 가시성을 가짐 (breaking change 예정)
val user = User.create("Alice", 25)
// val copied = user.copy(name = "Bob")  // 향후 접근 불가 예정

6. Kotlin Multiplatform 안정화

// 2.0에서 KMP(Kotlin Multiplatform)가 Stable 선언

// commonMain: iOS, Android, Desktop 공유
expect fun getPlatformName(): String

// androidMain
actual fun getPlatformName() = "Android"

// iosMain
actual fun getPlatformName() = "iOS"

Compose Multiplatform과 함께 단일 코드베이스로 멀티 플랫폼 UI 구성이 안정화됐습니다.


7. 기타 언어 변경사항

람다 파라미터에서 언더스코어 사용

// 사용하지 않는 파라미터를 _ 로 표시 (Kotlin 2.0 안정화)
val map = mapOf("a" to 1, "b" to 2)
map.forEach { (_, value) ->  // 키는 무시
    println(value)
}

// 여러 파라미터 무시
listOf(1, 2, 3).mapIndexed { _, value -> value * 2 }

타입 별칭 개선

// 2.0: 타입 별칭에 제네릭 제약 지원
typealias StringMap<V> = Map<String, V>
typealias Callback = (String) -> Unit

8. K2로 마이그레이션

// build.gradle.kts
plugins {
    kotlin("android") version "2.0.0"
}

// Kapt → KSP 전환 권장 (K2와 더 잘 호환)
// kapt("...") → ksp("...")
K2 마이그레이션 체크리스트:
✓ Kotlin 2.0.0 이상 업그레이드
✓ Gradle 8.x 이상 권장
✓ kapt → ksp 전환 (점진적으로)
✓ 컴파일 경고 확인 (스마트 캐스트 관련)
✓ 서드파티 컴파일러 플러그인 K2 지원 여부 확인

9. K1 vs K2 비교

구분 K1 (기존) K2 (2.0+)
아키텍처 프론트엔드/백엔드 분리 통합 IR 기반
컴파일 속도 기준 최대 2배 향상
스마트 캐스트 보수적 더 정확한 분석
IDE 분석 별도 분석기 컴파일러와 통합
KMP 지원 실험적 Stable

10. 정리



Related Posts