본문 바로가기
Kotlin/What's new

[Kotlin 번역] What's new in Kotlin 1.5.30

by 노력남자 2023. 9. 17.
반응형

2021년 8월 24일

 

Kotlin 1.5.30는 미래 변경 사항의 미리보기를 포함한 언어 업데이트, 플랫폼 지원 및 도구에서의 다양한 개선 사항, 그리고 새로운 표준 라이브러리 함수를 제공합니다.

다음은 주요 개선 사항입니다:

  • 실험적인 sealed when 문을 포함한 언어 기능, opt-in 요구 사항 사용 변경 등
  • Apple 실리콘에 대한 네이티브 지원
  • Kotlin/JS IR 백엔드 베타 버전
  • 개선된 Gradle 플러그인 경험


릴리스 블로그 게시물과 이 비디오에서 변경 사항의 간략한 개요도 찾을 수 있습니다.

 


언어 기능


Kotlin 1.5.30은 미래 언어 변경 사항의 미리보기를 제공하고 opt-in 요구 사항 메커니즘 및 형 추론에 개선 사항을 가져옵니다.

  • sealed 및 Boolean 주체에 대한 완전한 when 문
  • 슈퍼 타입으로서의 중단 함수
  • 실험적인 API의 암묵적 사용에 대한 opt-in 필요
  • 다른 대상과 함께 opt-in 요구 사항 어노테이션 사용 변경
  • 재귀적 제네릭 유형의 형 추론 개선 사항

 

sealed 및 Boolean 주체에 대한 완전한 when 문


완전한 when 문은 sealed 및 Boolean 주체에 대한 지원입니다. 실험적이며 언제든지 변경되거나 삭제될 수 있습니다. 사용 시 opt-in이 필요하며 평가 목적으로만 사용해야 합니다. 이에 대한 의견을 YouTrack에서 환영합니다.

완전한 when 문은 주체의 모든 가능한 유형 또는 값 또는 일부 유형과 else 브랜치에 대한 분기를 포함합니다. 다시 말해 모든 가능한 경우를 다룹니다.

우리는 곧 완전하지 않은 when 문을 금지하여 동작을 when 식과 일관되게 만들 계획입니다. 원활한 이전을 보장하기 위해 컴파일러를 설정하여 sealed 클래스나 Boolean과 함께 완전하지 않은 when 문에 대한 경고를 보고하도록 구성할 수 있습니다. 이러한 경고는 기본적으로 Kotlin 1.6에서 나타나며 나중에 오류로 전환됩니다.

열거형은 이미 경고를 받습니다.

sealed class Mode {
    object ON : Mode()
    object OFF : Mode()
}

fun main() {
    val x: Mode = Mode.ON
    when (x) {
        Mode.ON -> println("ON")
    }
    // 경고: sealed 클래스/인터페이스의 완전하지 않은 'when' 문은 1.7에서 금지됩니다. 'OFF' 또는 'else' 브랜치를 추가하세요.

    val y: Boolean = true
    when (y) {
        true -> println("true")
    }
    // 경고: 부울에 대한 완전하지 않은 'when' 문은 1.7에서 금지됩니다. 'false' 또는 'else' 브랜치를 추가하세요.
}


이 기능을 Kotlin 1.5.30에서 활성화하려면 언어 버전 1.6을 사용하세요. 또한 진행적 모드를 활성화하여 경고를 오류로 변경할 수 있습니다.

kotlin {
    sourceSets.all {
        languageSettings.apply {
            languageVersion = "1.6"
            //progressiveMode = true // 기본값은 false입니다.
        }
    }
}

 

슈퍼 타입으로서의 중단 함수


중단 함수를 슈퍼 타입으로서 사용하는 기능입니다. 실험적이며 언제든지 변경되거나 삭제될 수 있습니다. 사용 시 opt-in이 필요하며 평가 목적으로만 사용해야 합니다. 이에 대한 의견을 YouTrack에서 환영합니다.

Kotlin 1.5.30은 중단 함수 유형을 일부 제한 사항과 함께 슈퍼 타입으로 사용하는 미리보기를 제공합니다.

class MyClass: suspend () -> Unit {
    override suspend fun invoke() { TODO() }
}


기능에는 다음 제한 사항이 있습니다:

  • 일반 함수 유형과 중단 함수 유형을 혼용할 수 없습니다. 이것은 JVM 백엔드에서 중단 함수 유형의 구현 세부 정보 때문입니다. JVM 백엔드에서는 중단 함수 유형을 표시 인터페이스를 사용하여 일반 함수 유형으로 나타냅니다. 표시 인터페이스로 인해 슈퍼 인터페이스 중 어떤 것이 중단되었는지 알 수 없습니다.
  • 여러 중단 함수 슈퍼 타입을 사용할 수 없습니다. 유형 확인이 있는 경우 여러 일반 함수 슈퍼 타입도 사용할 수 없습니다.

 

실험적 API의 암묵적 사용에 대한 opt-in 필요


opt-in 요구 사항 메커니즘은 실험적입니다. 언제든지 변경될 수 있습니다. opt-in 방법을 참조하세요. 평가 목적으로만 사용하고 의견을 YouTrack에서 환영합니다.

라이브러리 작성자는 실험적 상태에 대한 정보를 사용자에게 알리기 위해 실험적 API를 opt-in으로 표시할 수 있습니다

. 컴파일러는 API를 사용하고 억제하기 위해 명시적 동의가 필요할 때 경고 또는 오류를 발생시킵니다.

Kotlin 1.5.30에서는 시그니처에 실험적 유형이 있는 선언을 모두 실험적으로 처리합니다. 즉, 실험적 API의 암묵적 사용에 대해서도 opt-in이 필요합니다. 예를 들어, 함수의 반환 유형이 실험적 API 요소로 표시되면 선언이 명시적으로 opt-in을 요구하지 않더라도 함수의 사용에 opt-in이 필요합니다.

// 라이브러리 코드

@RequiresOptIn(message = "This API is experimental.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
annotation class MyDateTime // Opt-in 필요 어노테이션

@MyDateTime
class DateProvider // opt-in을 요구하는 클래스

// 클라이언트 코드

// 경고: 실험적 API 사용
fun createDateSource(): DateProvider { /* ... */ }

fun getDate(): Date {
    val dateSource = createDateSource() // 또한 경고: 실험적 API 사용
    // ...
}

 

opt-in requiremetns에 대해서 더 알고 싶다면 여기를 참조바랍니다.

 

다양한 대상에 대한 opt-in 요구 사항 어노테이션 사용 변경 사항


opt-in 요구 사항 어노테이션을 다른 대상에 대해 사용하고 선언하는 새로운 규칙을 Kotlin 1.5.30에서 제공합니다. 컴파일 시간에 처리하기 어려운 사용 사례에 대해 오류를 보고합니다. Kotlin 1.5.30에서 다음과 같습니다:

  • 지역 변수와 값 매개 변수에 opt-in 요구 사항 어노테이션을 표시하는 것은 사용 사이트에서 금지됩니다.
  • override를 표시할 때 기본 선언도 표시해야 합니다.
  • 백킹 필드와 게터에 표시하는 것이 금지됩니다. 대신 기본 속성을 표시할 수 있습니다.
  • TYPE 및 TYPE_PARAMETER 어노테이션 대상을 opt-in 요구 사항 어노테이션 선언 사이트에서 표시하는 것이 금지됩니다.
  • 형 추론의 재귀 제네릭 유형 개선 사항

 

opt-in requiremetns에 대해서 더 알고 싶다면 여기를 참조바랍니다.

 

재귀적인 제네릭 유형에 대한 형 추론 개선


Kotlin과 Java에서 형 매개 변수에서 자체를 참조하는 재귀적 제네릭 유형을 정의할 수 있습니다. Kotlin 1.5.30에서 Kotlin 컴파일러는 재귀적 제네릭 유형인 경우 해당 형 매개 변수의 상한만을 기반으로 형 인수를 추론할 수 있습니다. 이로써 Java에서 일반적으로 빌더 API를 만드는 데 사용되는 재귀적 제네릭 유형 패턴을 만들 수 있게 됩니다.

// Kotlin 1.5.20
val containerA = PostgreSQLContainer<Nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
    withDatabaseName("db")
    withUsername("user")
    withPassword("password")
    withInitScript("sql/schema.sql")
}

// Kotlin 1.5.30
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
    .withDatabaseName("db")
    .withUsername("user")
    .withPassword("password")
    .withInitScript("sql/schema.sql")


-Xself-upper-bound-inference 또는 -language-version 1.6 컴파일러 옵션을 전달하여 개선 사항을 활성화할 수 있습니다. 이 YouTrack 티켓에서 지원되는 다른 사용 사례의 예제도 확인할 수 있습니다.


빌더 추론 제한 사항 제거


빌더 추론은 호출의 타입 인수를 람다 인수 내부의 다른 호출로부터 얻는 타입 추론의 특수한 종류입니다. 이것은 buildList() 또는 sequence()와 같은 제네릭 빌더 함수를 호출할 때 유용할 수 있습니다. buildList { add("string") }와 같은 제네릭 빌더 함수의 람다 인수 내부에서 이전에는 빌더 추론이 추론하려는 타입 정보를 사용하는 데 제한이 있었습니다. 다시 말해서 명시적으로 지정된 타입 인수 없이는 buildList()의 람다 인수 내부에서 get()을 호출할 수 없었습니다.

Kotlin 1.5.30은 -Xunrestricted-builder-inference 컴파일러 옵션을 통해 이러한 제한 사항을 제거합니다. 이 옵션을 추가하여 제네릭 빌더 함수의 람다 인수 내부에서 이전에 금지되었던 호출을 활성화할 수 있습니다.

@kotlin.ExperimentalStdlibApi
val list = buildList {
    add("a")
    add("b")
    set(1, null)
    val x = get(1)
    if (x != null) {
        removeAt(1)
    }
}

@kotlin.ExperimentalStdlibApi
val map = buildMap {
    put("a", 1)
    put("b", 1.1)
    put("c", 2f)
}


또한 이 기능을 -language-version 1.6 컴파일러 옵션으로 활성화할 수 있습니다.

 

Kotlin/JVM


Kotlin 1.5.30을 통해 Kotlin/JVM 플랫폼에서 다음과 같은 기능이 추가되었습니다.

  • 주석 클래스의 인스턴스화
  • 개선된 nullability 어노테이션 지원 구성


JVM 플랫폼에서 Kotlin Gradle 플러그인 업데이트에 대한 내용은 Gradle 섹션을 참조하십시오.


주석 클래스의 인스턴스화


주석 클래스의 인스턴스화는 실험적입니다. 언제든지 삭제 또는 변경될 수 있습니다. Opt-in이 필요하며 평가 목적으로만 사용해야 합니다. 이에 대한 피드백은 YouTrack에서 환영합니다.

Kotlin 1.5.30에서는 이제 임의의 코드에서 주석 클래스의 생성자를 호출하여 결과 인스턴스를 얻을 수 있습니다. 이 기능은 주석 인터페이스를 구현하는 Java 규칙과 동일한 사용 사례를 다룹니다.

annotation class InfoMarker(val info: String)

fun processInfo(marker: InfoMarker) = ...

fun main(args: Array<String>) {
    if (args.size != 0)
        processInfo(getAnnotationReflective(args))
    else
        processInfo(InfoMarker("default"))
}


이 기능을 활성화하려면 -language-version 1.6 컴파일러 옵션을 사용하세요. 주석 클래스에 대한 현재 제한 사항, 예를 들어 비-val 매개 변수 정의 또는 보조 생성자와 다른 멤버 정의 제한 등은 그대로 유지됩니다.

주석 클래스의 인스턴스화에 대한 자세한 내용은 이 KEEP에서 알아보세요.


개선된 nullability 어노테이션 지원 구성


Kotlin 컴파일러는 다양한 유형의 nullability 어노테이션을 읽어서 Java로부터 nullability 정보를 가져올 수 있습니다. 이 정보를 사용하여 Kotlin에서 Java 코드를 호출할 때 nullability 불일치를 보고할 수 있습니다.

Kotlin 1.5.30에서는 nullability 어노테이션의 특정 유형에서 가져온 정보를 기반으로 컴파일러가 nullability 불일치를 보고하는 방법을 지정할 수 있습니다. 컴파일러 옵션 -Xnullability-annotations=@<패키지-이름>:<보고-레벨>을 사용하세요. 인수에서 완전히 지정된 nullability 어노테이션 패키지와 다음 중 하나의 보고 레벨을 지정하세요.

  • ignore: nullability 불일치를 무시합니다.
  • warn: 경고를 보고합니다.
  • strict: 오류를 보고합니다.


지원되는 nullability 어노테이션 전체 목록과 완전히 지정된 패키지 이름을 함께 확인하세요.

다음은 새로 지원되는 RxJava 3 nullability 어노테이션에 대한 오류 보고를 활성화하는 방법을 보여주는 예제입니다: -Xnullability-annotations=@io.reactivex.rxjava3.annotations:strict. 모든 이러한 nullability 불일치는 기본적으로 경고입니다.

 

Kotlin/Native


Kotlin/Native에서는 다양한 변경 사항과 개선 사항이 있었습니다.

  • Apple silicon 지원
  • CocoaPods Gradle 플러그인을 위한 개선된 Kotlin DSL
  • Swift 5.5 async/await와의 실험적 상호 운용성
  • 객체 및 동반 객체에 대한 Swift/Objective-C 매핑 개선
  • MinGW 대상의 가져오기 라이브러리 없이 DLL에 대한 연결 사용의 폐기

 

Apple silicon 지원


Kotlin 1.5.30에서는 Apple silicon에 대한 원시 지원을 제공합니다.

이전에 Kotlin/Native 컴파일러 및 도구는 Apple silicon 호스트에서 작업하기 위해 Rosetta 번역 환경이 필요했습니다. Kotlin 1.5.30에서는 번역 환경이 더 이상 필요하지 않으며, 컴파일러와 도구는 추가 조치 없이도 Apple silicon 하드웨어에서 실행할 수 있습니다.

또한 Kotlin 코드를 Apple silicon에서 네이티브로 실행하는 데 사용되는 새로운 대상을 소개했습니다.

  • macosArm64
  • iosSimulatorArm64
  • watchosSimulatorArm64
  • tvosSimulatorArm64


이러한 대상은 Intel 기반 및 Apple silicon 호스트에서 모두 사용할 수 있습니다. 모든 기존 대상도 Apple silicon 호스트에서 사용 가능합니다.

참고로 1.5.30에서는 kotlin-multiplatform Gradle 플러그인에서 Apple silicon 대상에 대한 기본 지원만 제공합니다. 특히, 새로운 시뮬레이터 대상은 ios, tvos 및 watchos 대상 단축키에 포함되지 않습니다. 새로운 대상과 관련된 사용자 경험을 개선하기 위해 계속 노력하겠습니다.


CocoaPods Gradle 플러그인을 위한 개선된 Kotlin DSL

 

Kotlin/Native frameworks를 위한 새로운 파라미터


Kotlin/Native 프레임워크에 대한 개선된 CocoaPods Gradle 플러그인 DSL을 소개합니다. 이제 프레임워크의 이름뿐만 아니라 Pod 구성에서 다른 매개 변수를 지정할 수 있습니다.

  • 프레임워크의 동적 또는 정적 버전을 지정합니다.
  • 의존성 내보내기를 명시적으로 활성화합니다.
  • Bitcode 포함을 활성화합니다.


새로운 DSL을 사용하려면 프로젝트를 Kotlin 1.5.30으로 업데이트하고 build.gradle(.kts) 파일의 cocoapods 섹션에서 매개 변수를 지정하십시오.

cocoapods {
    frameworkName = "MyFramework" // 이 속성은 폐기 예정이며
    // 향후 버전에서 제거됩니다.
    // 프레임워크 구성을 위한 새로운 DSL:
    framework {
        // 모든 프레임워크 속성을 지원합니다.
        // 프레임워크 이름 구성. 폐기 예정인 'frameworkName' 대신 사용하세요.
        baseName = "MyFramework"
        // 동적 프레임워크 지원
        isStatic = false
        // 의존성 내보내기
        export(project(":anotherKMMModule"))
        transitiveExport = false // 이것이 기본값입니다.
        // Bitcode 포함
        embedBitcode(BITCODE)
    }
}


Xcode 구성에 대한 사용자 지정 이름 지원


Kotlin CocoaPods Gradle 플러그인은 Xcode 빌드 구성에서 사용자 지정 이름을 지원합니다. Xcode에서 빌드 구성에 특수한 이름을 사용하는 경우 도움이 됩니다.

사용자 지정 이름을 지정하려면 build.gradle(.kts) 파일의 cocoapods 섹션에서 xcodeConfigurationToNativeBuildType 매개 변수를 사용하세요.

cocoapods {
    // 사용자 정의 Xcode 구성을 NativeBuildType으로 매핑
    xcodeConfigurationToNativeBuildType["CUSTOM_DEBUG"] = NativeBuildType.DEBUG
    xcodeConfigurationToNativeBuildType["CUSTOM_RELEASE"] = NativeBuildType.RELEASE
}


이 매개 변수는 Podspec 파일에 나타나지 않습니다. Xcode가 Gradle 빌드 프로세스를 실행할 때 Kotlin CocoaPods Gradle 플러그인이 필요한 Native Build Type을 선택합니다.

기본적으로 Debug 및 Release 구성을 선언할 필요가 없습니다.


Swift 5.5 async/await와의 실험적 상호 운용성


Swift async/await와의 동시성 상호 운용성은 실험적입니다. 언제든지 삭제 또는 변경될 수 있습니다. 평가 목적으로만 사용해야 합니다. 이에 대한 피드백은 YouTrack에서 환영합니다.

우리는 1.4.0에서 Kotlin의 서스펜드 함수를 Objective-C 및 Swift에서 호출할 수 있도록 지원을 추가했으며, 이제는 새로운 Swift 5.5 기능인 async 및 await 수정자를 지원하기 위해 이를 개선하고 있습니다.

Kotlin/Native 컴파일러는 이제 null 가능한 반환 유형을 가진 서스펜드 함수에 대한 생성된 Objective-C 헤더에서 _Nullable_result 속성을 발생시킵니다. 이를 통해 Swift에서 이러한 함수를 올바른 null 가능성으로 async 함수로 호출할 수 있습니다.

이 기능은 실험적이며 미래에 Kotlin과 Swift 모두에서 변경될 수 있습니다. 현재 이 기능의 미리 보기를 제공하며 특정한 제한 사항이 있으며, 여러분의 의견을 듣고자 합니다. 현재 상태에 대한 자세한 내용은 이 YouTrack 이슈에서 확인하고 의견을 남겨주세요.


객체 및 동반 객체에 대한 Swift/Objective-C 매핑 개선


객체 및 동반 객체를 네이티브 iOS 개발자에게 더 직관적으로 사용할 수 있는 방식으로 가져올 수 있습니다. 예를 들어 Kotlin에 다음과 같은 객체이 있는 경우:

object MyObject {
    val x = "Some value"
}

class MyClass {
    companion object {
        val x = "Some value"
    }
}


Swift에서 이를 액세스하려면 shared 및 companion 속성을 사용할 수 있습니다:

MyObject.shared
MyObject.shared.x
MyClass.companion
MyClass.Companion.shared


Swift/Objective-C 상호 운용성에 대한 자세한 내용을 확인하세요.


MinGW 대상에서 가져오기 라이브러리 없이 DLL에 대한 연결 사용의 폐기


LLD는 LLVM 프로젝트의 링커로, Kotlin/Native의 MinGW 대상에서 기본 ld.bfd보다 성능이 더 좋아서 Kotlin/Native에서 MinGW 대상에 LLD 링커를 사용할 계획입니다.

그러나 현재 안정 버전의 LLD는 MinGW(Windows) 대상에서 DLL에 대한 직접 연결을 지원하지 않습니다. 이러한 연결을 위해서는 가져오기 라이브러리를 사용해야 합니다. Kotlin/Native 1.5.30에서는 이러한 라이브러리가 필요하지 않지만, 미래에 MinGW의 기본 링커로 사용될 LLD와 호환되지 않음을 알리기 위해 경고를 추가하고 있습니다.

LLD 링커로의 전환에 대한 의견과 우려를 이 YouTrack 이슈에서 공유해 주세요.

 

Kotlin Multiplatform


Kotlin 1.5.30에서 Kotlin Multiplatform에 다음과 같은 주요 업데이트가 있습니다:

  • 공유 네이티브 코드에서 사용자 정의 cinterop 라이브러리 사용 가능
  • XCFrameworks 지원
  • Android 아티팩트를 위한 새로운 기본 게시 설정


공유 네이티브 코드에서 사용자 정의 cinterop 라이브러리 사용 가능


Kotlin Multiplatform은 공유 소스 세트에서 플랫폼 종속적 인터랍 라이브러리를 사용하는 옵션을 제공합니다. 1.5.30 이전에는 Kotlin/Native 배포와 함께 제공되는 플랫폼 라이브러리와만 작동했습니다. 1.5.30부터는 사용자 정의 cinterop 라이브러리와 함께 사용할 수 있습니다. 이 기능을 활성화하려면 gradle.properties에 kotlin.mpp.enableCInteropCommonization=true 속성을 추가하세요:

kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
kotlin.mpp.enableCInteropCommonization=true


XCFrameworks 지원


모든 Kotlin Multiplatform 프로젝트는 이제 XCFrameworks를 출력 형식으로 사용할 수 있습니다. Apple은 XCFrameworks를 대체용으로 사용할 범용(fat) 프레임워크를 소개했습니다. XCFrameworks를 사용하면 다음과 같은 이점이 있습니다.

  • 모든 대상 플랫폼 및 아키텍처의 논리를 단일 번들에 모을 수 있습니다.
  • App Store에 애플리케이션을 게시하기 전에 모든 불필요한 아키텍처를 제거할 필요가 없습니다.

 

XCFrameworks는 Apple M1에서 기기 및 시뮬레이터용 Kotlin 프레임워크를 사용하려는 경우 유용합니다.

XCFrameworks를 사용하려면 build.gradle(.kts) 스크립트를 업데이트하세요:

import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

plugins {
    kotlin("multiplatform")
}

kotlin {
    val xcf = XCFramework()

    ios {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
    watchos {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
    tvos {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
}


XCFrameworks를 선언하면 다음과 같은 새로운 Gradle 작업이 등록됩니다.

  • assembleXCFramework
  • assembleDebugXCFramework (dSYM을 포함하는 추가 디버그 아티팩트)
  • assembleReleaseXCFramework


XCFrameworks에 대한 자세한 내용은 이 WWDC 비디오에서 확인할 수 있습니다.


Android 아티팩트를 위한 새로운 기본 게시 설정


maven-publish Gradle 플러그인을 사용하여 빌드 스크립트에서 Android 변형 이름을 지정하여 Android 대상을 위한 멀티플랫폼 라이브러리를 게시할 수 있습니다. Kotlin Gradle 플러그인은 게시판을 자동으로 생성합니다.

1.5.30 이전에 생성된 게시 메타데이터에는 모든 게시된 Android 변형에 대한 빌드 유형 속성이 포함되어 있어 라이브러리 사용자가 사용하는 동일한 빌드 유형과 호환되게 됩니다. Kotlin 1.5.30에서는 새로운 기본 게시 설정이 도입되었습니다.

  • 프로젝트가 게시하는 모든 Android 변형이 동일한 빌드 유형 속성을 가지면 게시된 변형에는 빌드 유형 속성이 없으며 모든 빌드 유형과 호환됩니다.
  • 게시된 변형이 다른 빌드 유형 속성을 가지는 경우 릴리스 값을 가진 변형만 빌드 유형 속성이 없이 게시됩니다. 이로써 릴리스 변형은 라이브러리 사용자의 빌드 유형과 호환되며 릴리스 이외의 변형은 해당하는 소비자 빌드 유형과만 호환됩니다.


빌드 유형 속성을 모든 변형에 유지하려면 kotlin.android.buildTypeAttribute.keep=true Gradle 속성을 설정하십시오.

 

Kotlin/JS


Kotlin 1.5.30에서 Kotlin/JS에는 다음과 같은 두 가지 주요 개선 사항이 있습니다.

  • JS IR 컴파일러 백엔드가 베타로 도달함
  • Kotlin/JS IR 백엔드를 사용하는 애플리케이션에 대한 개선된 디버깅 경험


JS IR 컴파일러 백엔드가 베타로 도달함


Kotlin/JS용 IR 기반 컴파일러 백엔드는 1.4.0에서 알파로 도입되었으며, 이제 베타로 도달했습니다.

이전에는 JS IR 백엔드로 프로젝트를 마이그레이션하는 데 도움이 되는 JS IR 백엔드 마이그레이션 가이드를 게시했습니다. 이제 IntelliJ IDEA에서 필요한 변경 사항을 직접 표시하는 Kotlin/JS Inspection Pack IDE 플러그인을 소개하고자 합니다.


Kotlin/JS IR 백엔드를 사용하는 애플리케이션의 개선된 디버깅 경험


Kotlin 1.5.30에서 Kotlin/JS IR 백엔드를 활성화하면 JavaScript 소스 맵 생성이 제공됩니다. 이로 인해 IR 백엔드가 활성화되면 Kotlin/JS 디버깅 경험이 향상되며 중단점, 단계별 실행 및 올바른 소스 참조를 갖춘 가독성 있는 스택 추적을 포함한 완전한 디버깅 지원이 가능해집니다.

브라우저나 IntelliJ IDEA Ultimate에서 Kotlin/JS를 디버깅하는 방법을 자세히 알아보세요.


Gradle


Kotlin Gradle 플러그인 사용자 경험을 개선하기 위해 다음과 같은 기능을 구현했습니다.

  • Java toolchains 지원: 구식 Gradle 버전을 위한 JDK 홈 지정을 포함한 UsesKotlinJavaToolchain 인터페이스 사용 가능
  • Kotlin 데몬 JVM 인수를 명시적으로 지정하는 간편한 방법 추가

 

Java toolchains 지원


Gradle 6.7에서는 "Java toolchains 지원" 기능을 도입했습니다. 이 기능을 사용하면 다음을 수행할 수 있습니다.

  • Gradle과 다른 JDK 및 JRE를 사용하여 컴파일, 테스트 및 실행 가능
  • 릴리스되지 않은 언어 버전으로 코드를 컴파일 및 테스트

 

toolchains 지원을 사용하면 Gradle이 로컬 JDK를 자동으로 감지하고 빌드에 필요한 JDK를 설치할 수 있습니다. 이제 Gradle 자체는 어떤 JDK에서나 실행하고 빌드 캐시 기능을 재사용할 수 있습니다.


Kotlin Gradle 플러그인은 Kotlin/JVM 컴파일 작업에 대한 Java toolchains을 지원합니다. Java toolchain은 다음을 수행합니다.

 

  • JVM 대상의 jdkHome 옵션 설정
    • jdkHome 옵션을 직접 설정하는 것이 더 이상 사용되지 않습니다.
  • 사용자가 명시적으로 jvmTarget 옵션을 설정하지 않은 경우 jvmTarget 옵션을 toolchain의 JDK 버전으로 설정합니다. toolchain이 구성되지 않은 경우 jvmTarget 필드는 기본값을 사용합니다. JVM 대상 호환성에 대한 자세한 내용을 확인하세요.
  • kapt 작업이 실행되는 JDK를 지정합니다.


다음 코드를 사용하여 toolchain을 설정합니다. <MAJOR_JDK_VERSION> 자리 표시자를 사용할 원하는 JDK 버전으로 바꿉니다.

kotlin {
    jvmToolchain {
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
    }
}


Kotlin 확장을 통해 toolchain을 설정하면 Java 컴파일 작업에도 동일한 toolchain이 적용됩니다. KotlinCompile 작업에 대한 JDK 버전을 설정하는 방법에 대한 자세한 내용은 Task

 DSL을 사용하여 JDK 버전 설정 문서를 참조하세요.

Gradle 버전 6.1부터 6.6까지는 UsesKotlinJavaToolchain 인터페이스를 사용하여 JDK 홈을 설정합니다. Gradle 6.7부터는 Java toolchains을 사용합니다.

 

UsesKotlinJavaToolchain 인터페이스를 사용하여 JDK 홈을 지정할 수 있는 능력


UsesKotlinJavaToolchain 인터페이스를 사용할 때 주의할 점은 kapt 작업 워커가 프로세스 분리 모드만 사용하고 kapt.workers.isolation 속성은 무시된다는 것입니다.

 

project.tasks
    .withType<UsesKotlinJavaToolchain>()
    .configureEach {
        it.kotlinJavaToolchain.jdk.use(
            "/path/to/local/jdk",
            JavaVersion.<LOCAL_JDK_VERSION>
        )
    }


Kotlin 데몬 JVM 인수를 명시적으로 지정하는 간편한 방법 추가


Kotlin 1.5.30에서 Kotlin 데몬의 JVM 인수에 대한 새로운 논리가 도입되었습니다. 다음 목록에서 각 옵션은 그 앞에 오는 옵션을 덮어씁니다.

- 아무것도 지정하지 않으면 Kotlin 데몬은 Gradle 데몬에서 인수를 상속합니다(이전과 동일).

 

org.gradle.jvmargs=-Xmx1500m -Xms=500m


- Gradle 데몬의 JVM 인수에 kotlin.daemon.jvm.options 시스템 속성이 있으면 이를 이전과 같이 사용합니다.

 

org.gradle.jvmargs=-Dkotlin.daemon.jvm.options=-Xmx1500m -Xms=500m


- gradle.properties 파일에서 kotlin.daemon.jvmargs 속성을 추가할 수 있습니다.

 

kotlin.daemon.jvmargs=-Xmx1500m -Xms=500m


- kotlin 확장에서 인수를 지정할 수 있습니다.

 

kotlin {
    kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
}


- 특정 작업에 대한 인수를 지정할 수 있습니다.

 

tasks
    .matching { it.name == "compileKotlin" && it is CompileUsingKotlinDaemon }
    .configureEach {
        (this as CompileUsingKotlinDaemon).kotlinDaemonJvmArguments.set(listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"))
    }

 

표준 라이브러리


이 경우 새로운 Kotlin 데몬 인스턴스가 작업 실행 시 시작될 수 있습니다. Kotlin 데몬과 JVM 인수의 상호 작용에 대한 자세한 내용은 Kotlin 데몬 및 Gradle에서 사용하는 방법을 참조하세요.

 

Kotlin 1.5.30에서는 표준 라이브러리의 Duration 및 Regex API에 대한 개선 사항이 제공됩니다:

  • Duration.toString() 출력 변경
  • 문자열에서 Duration 파싱
  • Regex에서 특정 위치와 일치
  • Regex를 시퀀스로 분할

 

Duration.toString() 출력 변경


Duration API는 실험적입니다. 언제든지 변경 또는 폐기될 수 있습니다. 평가 목적으로만 사용하십시오. 여러분의 피드백을 YouTrack에서 기다리고 있습니다.

Kotlin 1.5.30 이전에는 Duration.toString() 함수가 가장 간결하고 가독성 있는 숫자 값을 출력한 단위로 표현된 인수의 문자열 표현을 반환했습니다. 이제부터는 각각 자체 단위로 표현된 숫자 구성 요소를 포함한 문자열 값이 반환됩니다. 각 구성 요소는 숫자 다음에 단위의 약어 이름인 d, h, m, s가 따릅니다. 예를 들어:


음수 지속 시간의 표현 방식도 변경되었습니다. 음수 지속 시간은 음수 부호 (-)로 시작하며 여러 구성 요소로 이루어져 있으면 괄호로 묶입니다. 예를 들면 -12m 및 -(1h 30m)입니다.

참고로 1초 미만의 작은 지속 시간은 하나의 숫자로 표시되며 하위 초(second) 단위(ms, us, ns) 중 하나를 사용합니다. 예를 들어 140.884ms, 500us, 24ns입니다. 이제 이러한 시간 간격은 지수 표기법을 사용하여 표시하지 않습니다.

하나의 단위로 지속 시간을 표현하려면 Duration.toString(unit, decimals) 함수를 사용하십시오.

일부 경우, 직렬화 및 교환을 포함하여 Duration.toString() 대신 보다 엄격한 ISO-8601 형식을 사용하는 Duration.toIsoString()을 사용하는 것이 좋습니다.


문자열에서 Duration 파싱


Duration API는 실험적입니다. 언제든지 변경 또는 폐기될 수 있습니다. 평가 목적으로만 사용하십시오. 이 문제에서 여러분의 피드백을 기다리고 있습니다.

Kotlin 1.5.30에서 Duration API에는 다음과 같은 새로운 함수가 있습니다:

 

  • parse(): 이 함수는 다음에서 출력을 파싱하는 데 사용됩니다:
    • toString().
    • toString(unit, decimals).
    • toIsoString().
  • parseIsoString(): 이 함수는 toIsoString()에서 생성된 형식에서만 파싱합니다.
  • parseOrNull() 및 parseIsoStringOrNull(): 이러한 함수는 유효하지 않은 지속 시간 형식에 대한 IllegalArgumentException을 던지지 않고 null을 반환하는 점을 제외하고 위의 함수와 동일한 방식으로 작동합니다.


다음은 parse() 및 parseOrNull() 사용 예입니다:

val isoFormatString = "PT1H30M"
val defaultFormatString = "1h 30m"
val singleUnitFormatString = "1.5h"
val invalidFormatString = "1 hour 30 minutes"
println(Duration.parse(isoFormatString)) // "1h 30m"
println(Duration.parse(defaultFormatString)) // "1h 30m"
println(Duration.parse(singleUnitFormatString)) // "1h 30m"
//println(Duration.parse(invalidFormatString)) // 예외를 발생시킵니다.
println(Duration.parseOrNull(invalidFormatString)) // "null"


다음은 parseIsoString() 및 parseIsoStringOrNull() 사용 예입니다:

val isoFormatString = "PT1H30M"
val defaultFormatString = "1h 30m"
println(Duration.parseIsoString(isoFormatString)) // "1h 30m"
//println(Duration.parseIsoString(defaultFormatString)) // 예외를 발생시킵니다.
println(Duration.parseIsoStringOrNull(defaultFormatString)) // "null"

 

특정 위치에서 Regex와 일치하는 것 확인하기


Regex.matchAt() 및 Regex.matchesAt() 함수는 실험적입니다. 언제든지 변경 또는 폐기될 수 있습니다. 평가 목적으로만 사용하십시오. 이에 대한 여러분의 피드백을 YouTrack에서 기다리고 있습니다.

새로운 Regex.matchAt() 및 Regex.matchesAt() 함수는 문자열 또는 CharSequence의 특정 위치에서 정규 표현식이 정확히 일치하는지 확인하는 방법을 제공합니다.

matchesAt()는 부울 결과를 반환합니다:

val releaseText = "Kotlin 1.5.30 is released!"
// 정규 표현식: 하나의 숫자, 점, 하나의 숫자, 점, 하나 이상의 숫자
val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
println(versionRegex.matchesAt(releaseText, 0)) // "false"
println(versionRegex.matchesAt(releaseText, 7)) // "true"


matchAt()는 일치하는 경우 일치 항목을 반환하거나 일치하는 항목이 없는 경우 null을 반환합니다:

val releaseText = "Kotlin 1.5.30 is released!"
val versionRegex = "\\d[.]\\d[.]\\d+".to

Regex()
println(versionRegex.matchAt(releaseText, 0)) // "null"
println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"

 

정규 표현식을 시퀀스로 분할


Regex.splitToSequence() 및 CharSequence.splitToSequence(Regex) 함수도 실험적입니다. 언제든지 변경 또는 폐기될 수 있습니다. 평가 목적으로만 사용하십시오. 이에 대한 여러분의 피드백을 YouTrack에서 기다리고 있습니다.

 

Regex.splitToSequence() 및 CharSequence.splitToSequence(Regex) 함수는 실험적입니다. 언제든지 삭제되거나 변경될 수 있습니다. 평가 목적으로만 사용하십시오. 여러분의 의견을 YouTrack에서 듣고 싶습니다.

새로운 Regex.splitToSequence() 함수는 split()의 지연 버전입니다. 주어진 정규 표현식의 일치 항목 주변에서 문자열을 분할하지만 결과를 시퀀스로 반환하여이 결과의 모든 작업이 지연 실행됩니다.

예시:

 

val colorsText = "green, red , brown&blue, orange, pink&green"
val regex = "[,\\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
    .onEach { println(it) }
    .firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"


CharSequence에도 유사한 함수가 추가되었습니다.


직렬화 1.3.0-RC


kotlinx.serialization 1.3.0-RC는 새로운 JSON 직렬화 기능을 갖고 왔습니다:

  • Java IO 스트림 직렬화
  • 기본 값에 대한 속성 수준의 제어
  • 직렬화에서 null 값을 제외하는 옵션
  • 다형성 직렬화에서 사용자 지정 클래스 판별자

 

변경 로그에서 자세히 알아보십시오.

 

원문

 

https://kotlinlang.org/docs/whatsnew1530.html

반응형

댓글