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

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

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

2021년 11월 16일

 
Kotlin 1.6.0은 새로운 언어 기능, 최적화 및 기존 기능의 개선, 그리고 Kotlin 표준 라이브러리에 대한 다양한 개선 사항을 제공합니다.

릴리스 블로그 게시물에서 변경 사항 개요를 찾을 수도 있습니다.
 

언어

 
코틀린 1.6.0 버전은 이전 1.5.30 릴리스에서 미리보기로 도입된 여러 언어 기능에 안정성을 가져왔습니다:

  • Enum, sealed 및 Boolean 주제에 대한 안정적인 완전한 when 문
  • 안정적인 서스펜딩 함수의 상위 유형
  • 안정적인 서스펜드 변환
  • 주석 클래스의 안정적인 인스턴스화


또한 여러 유형 추론 개선 및 클래스 유형 매개 변수에 대한 주석 지원이 포함되었습니다:

  • 재귀적 제네릭 유형의 유형 추론 개선
  • 빌더 유추 변경 사항
  • 클래스 유형 매개 변수에 대한 주석 지원


안정적인 완전한 enum, sealed 및 Boolean 주제의 when 문


완전한 when 문은 주제의 모든 가능한 유형 또는 값 또는 일부 유형과 else 분기를 포함합니다. 이것은 모든 가능한 경우를 다루어 코드를 더 안전하게 만듭니다.

향후 릴리스에서 when 식과 일관된 동작을 위해 비완전한 when 문을 금지할 예정입니다. 원활한 이전을 보장하기 위해 Kotlin 1.6.0은 enum, sealed 또는 Boolean 주제와 관련된 비완전한 when 문에 대한 경고를 보고합니다. 이러한 경고는 향후 릴리스에서 오류로 변환될 것입니다.

sealed class Contact {
    data class PhoneCall(val number: String) : Contact()
    data class TextMessage(val number: String) : Contact()
}

fun Contact.messageCost(): Int =
    when(this) { // 오류: 'when' 식은 완전해야 합니다
        is Contact.PhoneCall -> 42
    }

fun sendMessage(contact: Contact, message: String) {
    // 1.6.0부터 시작

    // 경고: 1.7에서 Boolean에 대한 비완전한 'when' 문은 금지됩니다. 'false' 분기 또는 'else' 분기를 추가하세요.
    when(message.isEmpty()) {
        true -> return
    }
    // 경고: 1.7에서 비완전한 'when' 문은 sealed 클래스/인터페이스에서 금지됩니다. 'is TextMessage' 분기 또는 'else' 분기를 추가하세요.
    when(contact) {
        is Contact.PhoneCall -> TODO()
    }
}


이 변경과 그 효과에 대한 자세한 설명은 해당 YouTrack 티켓을 참조하십시오.


안정적인 서스펜딩 함수의 상위 유형


코틀린 1.6.0에서 서스펜딩 기능 유형의 구현이 안정화되었습니다. 1.5.30에서 미리보기로 사용 가능했습니다.

이 기능은 Kotlin 코루틴을 사용하고 서스펜딩 기능 유형을 수용하는 API를 디자인할 때 유용할 수 있습니다. 이제 원하는 동작을 수행하는 별도의 클래스를 구현하여 서스펜딩 기능 유형을 구현할 수 있습니다.

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

fun launchOnClick(action: suspend () -> Unit) {}


이 클래스의 인스턴스를 이전에는 람다 및 서스펜딩 함수 참조만 허용되던 곳에서 사용할 수 있습니다: `launchOnClick(MyClickAction())`.

현재 구현 세부 정보에서 오는 두 가지 제한 사항이 있습니다:

  • 보통의 기능 유형과 서스펜딩 기능 유형을 유형 목록에서 혼용할 수 없습니다.
  • 여러 서스펜딩 기능 상위 유형을 사용할 수 없습니다.


안정적인 서스펜드 변환


코틀린 1.6.0에서는 일반적인 함수 유형에서 서스펜딩 기능 유형으로의 안정적인 변환을 소개합니다. 1.4.0부터 이 기능은 기능 리터럴 및 호출 가능한 참조를 지원했습니다. 1.6.0부터는 어떤 형태의 표현도 작동합니다. 호출 인수로는 서스펜딩이 예상되는 적합한 일반적인 함수 유형의 표현을 전달할 수 있습니다. 컴파일러는 자동으로 암시적 변환을 수행합니다.

fun getSuspending(suspending: suspend () -> Unit) {}

fun suspending() {}

fun test(regular: () -> Unit) {
    getSuspending { }           // OK
    getSuspending(::suspending) // OK
    getSuspending(regular)      // OK
}


주석 클래스의 안정적인 인스턴스화


코틀린 1.5.30에서는 JVM 플랫폼에서 주석 클래스의 인스턴스화를 실험적으로 지원했습니다. 1.6.0에서는 Kotlin/JVM 및 Kotlin/JS 모두에서 기본적으로 사용 가능한 기능입니다.

이 기능에 대한 자세한 내용은 해당 KEEP에서 확인할 수 있습니다.


재귀적 제네릭 유형의 유형 추론 개선


코틀린 1.5.30에서는 해당 유형 인자가 해당 유형 매개 변수의 상한만을 기반으로 추론할 수 있게

 해주는 재귀적 제네릭 유형의 유형 추론 개선이 소개되었습니다. 이 개선 사항은 컴파일러 옵션을 통해 사용할 수 있었습니다. 버전 1.6.0 이후로는 기본적으로 활성화되었습니다.

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

// 1.5.30에서 컴파일러 옵션 또는 1.6.0부터 기본적으로 사용
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
  .withDatabaseName("db")
  .withUsername("user")
  .withPassword("password")
  .withInitScript("sql/schema.sql")


빌더 유추 변경 사항


빌더 유추는 일반적인 빌더 함수를 호출할 때 유형 정보를 람다 인수 내부의 호출에서 가져올 수 있는 유형 추론 스타일입니다. 1.6.0부터 다음과 같은 변경 사항을 도입하고 있습니다:

  • -Xunrestricted-builder-inference 컴파일러 옵션을 지정하지 않고도 빌더 람다 내부에서 아직 추론되지 않은 유형의 인스턴스를 반환하는 호출을 수행할 수 있습니다.
  • -Xenable-builder-inference를 사용하여 @BuilderInference 주석을 적용하지 않고도 사용자 정의 빌더를 작성할 수 있습니다.


이러한 빌더의 클라이언트는 동일한 -Xenable-builder-inference 컴파일러 옵션을 지정해야 합니다.
 

  • -Xenable-builder-inference를 사용하면 보통의 유형 추론이 유형에 대한 충분한 정보를 얻을 수 없는 경우 빌더 유추가 자동으로 활성화됩니다.


사용자 정의 일반적인 빌더를 작성하는 방법에 대한 자세한 내용은 해당 문서를 참조하십시오.


클래스 유형 매개 변수에 대한 주석 지원


클래스 유형 매개 변수에 대한 주석 지원은 다음과 같습니다:

@Target(AnnotationTarget.TYPE_PARAMETER)
annotation class BoxContent

class Box<@BoxContent T> {}


모든 유형 매개 변수에 대한 주석은 JVM 바이트 코드로 생성되므로 주석 프로세서에서 사용할 수 있습니다.

자세한 사용 사례에 대해서는 해당 YouTrack 티켓을 확인하십시오.

주석에 대해 더 알아보기
 

이전 API 버전을 더 긴 기간 동안 지원

 
Kotlin 1.6.0부터 이전 API 버전을 더 오랜 기간 동안 지원할 것입니다. 현재는 안정된 현재 버전과 함께 1.3, 1.4, 1.5 및 1.6 버전을 지원합니다.


Kotlin/JVM


Kotlin/JVM에 대해서는 1.6.0부터 컴파일러가 JVM 17에 해당하는 바이트 코드 버전을 생성할 수 있습니다. 새로운 언어 버전에는 로드맵에 있던 최적화된 위임된 프로퍼티 및 반복 가능한 어노테이션도 포함되어 있습니다.

  • 1.8 JVM 대상으로 런타임 보존을 갖는 반복 가능한 어노테이션
  • 주어진 KProperty 인스턴스에서 get/set을 호출하는 최적화된 위임 프로퍼티 최적화


1.8 JVM 대상으로 런타임 보존을 갖는 반복 가능한 어노테이션


Java 8에서는 반복 가능한 어노테이션을 소개했으며, 이를 단일 코드 요소에 여러 번 적용할 수 있습니다. 이 기능은 Java 코드에 두 가지 선언이 있어야 합니다. 반복 가능한 어노테이션 자체는 @java.lang.annotation.Repeatable로 표시되어야 하며, 그 값을 보유할 포함 어노테이션도 있어야 합니다.

Kotlin도 반복 가능한 어노테이션을 갖고 있지만 어노테이션 선언에만 @kotlin.annotation.Repeatable이 있으면 반복 가능하도록 만들 수 있습니다. 1.6.0 이전에는 이 기능이 SOURCE 보존만 지원하고 Java의 반복 가능한 어노테이션과 호환되지 않았습니다. Kotlin 1.6.0에서는 이러한 제한 사항을 제거합니다. @kotlin.annotation.Repeatable은 이제 모든 보존을 허용하고 Kotlin 및 Java에서 모두 어노테이션을 반복 가능하게 만듭니다. Kotlin 측에서도 이제 Java의 반복 가능한 어노테이션을 지원합니다.

포함 어노테이션을 선언할 수 있지만 필수는 아닙니다. 예를 들면:

- 어노테이션 @Tag가 @kotlin.annotation.Repeatable로 표시되면 Kotlin 컴파일러가 자동으로 @Tag.Container라는 이름의 포함 어노테이션 클래스를 생성합니다.

@Repeatable
annotation class Tag(val name: String)

// 컴파일러는 @Tag.Container를 포함하는 어노테이션으로 생성합니다.


- 포함 어노테이션의 사용자 정의 이름을 설정하려면 @kotlin.jvm.JvmRepeatable 메타 어노테이션을 적용하고 명시적으로 선언된 포함 어노테이션 클래스를 인수로 전달하세요.

@JvmRepeatable(Tags::class)
annotation class Tag(val name: String)

annotation class Tags(val value: Array<Tag>)


Kotlin 리플렉션은 이제 Kotlin 및 Java의 반복 가능한 어노테이션을 KAnnotatedElement.findAnnotations() 함수를 통해 지원합니다.

Kotlin 반복 가능한 어노테이션에 대해 더 알아보려면 이 KEEP 문서를 참조하세요.


KProperty 인스턴스에서 get/set을 호출하는 최적화된 위임 프로퍼티 최적화


Kotlin은 참조된 프로퍼티에 대한 $delegate 필드를 생략하고 참조된 프로퍼티에 대한 직접적인 액세스를 생성하여 생성된 JVM 바이트 코드를 최적화했습니다.

예를 들어 다음 코드에서:

class Box<T> {
    private var impl: T = ...

    var content: T by ::impl
}


Kotlin은 이제 content$delegate 필드를 생성하지 않습니다. content 변수의 프로퍼티 액세서는 delegated property의 getValue/setValue 연산자를 건너뛰고 impl 변수를 직접 호출하므로 KProperty 유형의 프로퍼티 참조 객체가 필요하지 않습니다.

Google 동료들에게 이 구현에 감사드립니다!

위임된 프로퍼티에 대해 더 알아보기.
 

Kotlin/Native


Kotlin/Native은 여러 개의 개선 사항과 구성 요소 업데이트를 받고 있으며, 그 중 일부는 미리보기 상태입니다:

  • 새로운 메모리 관리자 미리보기
  • Xcode 13 지원
  • 어떤 호스트에서도 Windows 대상 컴파일
  • LLVM 및 링커 업데이트
  • 성능 개선
  • JVM 및 JS IR 백엔드와 통합된 컴파일러 플러그인 ABI
  • klib 링크 실패에 대한 자세한 오류 메시지
  • 재설계된 처리되지 않은 예외 처리 API 미리보기

 

새로운 메모리 관리자 미리보기


새로운 Kotlin/Native 메모리 관리자는 실험적인 상태입니다. 언제든지 중단되거나 변경될 수 있습니다. Opt-in(자발적 동의)이 필요하며 평가 목적으로만 사용해야 합니다. 이에 대한 피드백을 YouTrack에서 받아보겠습니다.

Kotlin 1.6.0에서는 새로운 Kotlin/Native 메모리 관리자의 개발 미리보기를 시도할 수 있습니다. 이로써 JVM과 Native 플랫폼 간의 차이를 줄이고 멀티플랫폼 프로젝트에서 일관된 개발자 경험을 제공하는 방향으로 나아갑니다.

주목할만한 변경 중 하나는 Kotlin/JVM과 같이 최상위 프로퍼티의 지연 초기화입니다. 최상위 프로퍼티는 동일한 파일에서 처음으로 최상위 프로퍼티나 함수에 접근할 때 초기화됩니다. 이 모드는 릴리스 이진 파일에만 활성화됩니다. 이것은 중복 초기화 검사를 제거하는 전역 상호 최적화를 포함합니다.

최신 메모리 관리자에 대한 현재 상태 및 데모 프로젝트를 찾으려면 최근 블로그 게시물을 확인하거나 직접 시도해보기 위한 이전 이전 지침으로 이동하십시오. 새 메모리 관리자가 프로젝트에서 어떻게 작동하는지 확인하고, 문제 추적기인 YouTrack에서 피드백을 공유해 주시기 바랍니다.


Xcode 13 지원


Kotlin/Native 1.6.0은 Xcode 13을 지원합니다. Apple 운영 체제용 Kotlin 프로젝트를 계속하여 업데이트하고 Xcode를 사용하십시오.

Xcode 13에서 추가된 새 라이브러리는 Kotlin 1.6.0에서 사용할 수 없지만, 향후 버전에서 이를 지원할 예정입니다.


어떤 호스트에서도 Windows 대상 컴파일


1.6.0부터는 Windows 호스트가 필요하지 않고 Kotlin/Native를 지원하는 모든 호스트에서 Windows 대상 mingwX64 및 mingwX86을 컴파일할 수 있습니다.


LLVM 및 링커 업데이트


Kotlin/Native이 내부적으로 사용하는 LLVM 종속성을 다시 작업했습니다. 이로 인해 다음과 같은 여러 이점이 있습니다:

  • LLVM 버전을 11.1.0으로 업데이트.
  • 종속성 크기 감소. 예를 들어 macOS에서는 이전 버전의 1200MB 대신 현재 버전에서 약 300MB입니다.
  • 현대 Linux 배포판에서 사용할 수 없는 ncurses5 라이브러리에 대한 종속성 제외.


LLVM 업데이트 외에도 Kotlin/Native은 이제 MinGW 대상에 대한 LLD 링커 (LLVM 프로젝트의 링커)를 사용합니다. 이것은 이전에 사용되던 ld.bfd 링커보다 여러 가지 이점을 제공하며, 생성된 바이너리의 실행시 성능을 향상시키고 MinGW 대상에 대한 컴파일러 캐시를 지원할 수 있게 해줍니다. LLD는 DLL 링크에 대한 가져오기 라이브러리가 필요합니다. 자세한 내용은 이 Stack Overflow 쓰레드에서 알아보십시오.


성능 개선


Kotlin/Native 1.6.0은 다음과 같은 성능 개선을 제공합니다:

  • 컴파일 시간: 컴파일러 캐시는 linuxX64 및 iosArm64 대상에 대해 기본적으로 활성화됩니다. 디버그 모드에서 대부분의 컴파일을 가속화합니다 (첫 번째 컴파일을 제외한 모든 컴파일). 측정 결과, 테스트 프로젝트에서 약 200% 속도 향상이 나타났습니다. 컴파일러 캐시는 Kotlin 1.5.0부터 이러한 대상에 대해 사용 가능했으며 추가 Gradle 속성이 필요했습니다. 이제 이러한 속성을 제거할 수 있습니다.
  • 런타임: 배열을 for 루프로 반복하는 것은 이제 생성된 LLVM 코드의 최적화로 인해 최대 12% 빨라졌습니다.

 

JVM 및 JS IR 백엔드와 통합된 컴파일러 플러그인 ABI


Kotlin/Native을 위한 공통 IR 컴파일러 플러그인 ABI를 사용할 수 있는 옵션은 실험적인 상태입니다. 언제든지 중단되거나 변경될 수 있습니다. Opt-in(자발적 동의)이 필요하며 평가 목적으로만 사용해야 합니다. 이에 대한 피드백을 YouTrack에서 받아보겠습니다.

이전 버전에서는 컴파일러 플러그인의 저자들이 ABI의 차이 때문에 Kotlin/Native을 위해 별도의 아티팩트를 제공해야 했습니다.

1.6.0부터 Kotlin Multiplatform Gradle 플러그인은 Kotlin/Native을 위해 사용되는 JVM 및 JS IR 백엔드에 사용되는 포함 가능한 컴파일러 jar를 사용할 수 있습니다. 이로써 네이티브 및 기타 지원되는 플랫폼에 대해 동일한 컴파일러 플러그인 아티팩트를 사용할 수 있게 되어 컴파일러 플러그인 개발 경험을 통합하는 단계입니다.

이것은 이러한 지원의 미리보기 버전이며, opt-in이 필요합니다. Kotlin/Native을 위한 일반 컴파일러 플러그인 아티팩트를 사용하기 시작하려면 gradle.properties에 다음 라인을 추가하십시오: kotlin.native.useEmbeddableCompilerJar=true.

향후에는 Kotlin/Native을 위한 기본적으로 포함 가능한 컴파일러 jar를 사용할 계획이므로 미리보기가 어떻게 작동하는지에 대한 피드백을 듣는 것이 중요합니다.

컴파일러 플러그인의 저자인 경우, 이 모드를 시도하고 플러그인이 작동하는지 확인하십시오. 플러그인의 구조에 따라 이전 버전에서 마이그레이션 단계가 필요할 수 있습니다. 마이그레이션 지침은 이 YouTrack 이슈를 참조하고 댓글에서 피드백을 남겨 주십시오.
 

klib 링크 실패에 대한 자세한 오류 메시지


Kotlin/Native 컴파일러는 이제 klib 링크 오류에 대한 자세한 오류 메시지를 제공합니다. 이제 메시지에는 명확한 오류 설명이 포함되어 있으며 가능한 원인 및 수정 방법에 대한 정보도 포함되어 있습니다.

예를 들어:

- 1.5.30:
 

e: java.lang.IllegalStateException: IrTypeAliasSymbol expected: Unbound public symbol for public kotlinx.coroutines/CancellationException|null[0]
<stack trace>


- 1.6.0:

e: The symbol of unexpected type encountered during IR deserialization: IrClassPublicSymbolImpl, kotlinx.coroutines/CancellationException|null[0].
IrTypeAliasSymbol is expected.

This could happen if there are two libraries, where one library was compiled against the different version of the other library than the one currently used in the project.
Please check that the project configuration is correct and has consistent versions of dependencies.

The list of libraries that depend on "org.jetbrains.kotlinx:kotlinx-coroutines-core (org.jetbrains.kotlinx:kotlinx-coroutines-core-macosx64)" and may lead to conflicts:
<list of libraries and potential version mismatches>

Project dependencies:
<dependencies tree>


재설계된 처리되지 않은 예외 처리 API


Kotlin/Native 런타임 전반에서 처리되지 않은 예외의 처리를 통합하고 사용자 지정 실행 환경(예: kotlinx.coroutines)에서 사용할 수 있도록 기본 처리를 processUnhandledException(throwable: Throwable) 함수로 노출시켰습니다. 이 처리는 Worker.executeAfter()에서 작업을 벗어난 예외에도 적용되지만 새로운 메모리 관리자에 대해서만 적용됩니다.

API 개선 사항은 또한 setUnhandledExceptionHook()에 설정된 후크에 영향을 미쳤습니다. 이전에는 이러한 후크가 처리되지 않은 예외와 함께 호출된 후에 재설정되었으며

 프로그램은 항상 이후에 종료되었습니다. 이제 이러한 후크를 여러 번 사용할 수 있으며 처리되지 않은 예외가 항상 프로그램을 종료하려면 처리되지 않은 예외 후크를 설정하지 않거나 후크의 끝에서 terminateWithUnhandledException()을 호출하십시오. 이렇게 하면 예외를 제3자 충돌 보고 서비스(예: Firebase Crashlytics)로 보내고 프로그램을 종료할 수 있습니다. main()에서 벗어난 예외와 interop 경계를 넘어가는 예외는 후크가 terminateWithUnhandledException()을 호출하지 않았더라도 프로그램을 항상 종료합니다.

Kotlin/JS


Kotlin/JS 컴파일러의 IR 백엔드 안정화 작업을 계속 진행 중입니다. Kotlin/JS에는 이제 Node.js와 Yarn을 다운로드하지 않도록 할 수 있는 옵션이 있습니다.
 

사전 설치된 Node.js와 Yarn 사용 옵션


이제 Kotlin/JS 프로젝트를 빌드할 때 Node.js와 Yarn을 다운로드하지 않고 호스트에 이미 설치된 인스턴스를 사용할 수 있습니다. 이것은 인터넷 연결이 없는 서버(예: CI 서버)에서 빌드할 때 유용합니다.

외부 구성 요소 다운로드 비활성화를 위해 build.gradle(.kts)에 다음 라인을 추가하십시오:

Yarn:
 

rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
    rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().download = false // 또는 기본 동작을 위해 true
}


Node.js:
 

rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
    rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().download = false // 또는 기본 동작을 위해 true
}


Kotlin Gradle 플러그인


Kotlin 1.6.0에서는 KotlinGradleSubplugin 클래스의 폐기 수준을 'ERROR'로 변경했습니다. 이 클래스는 컴파일러 플러그인을 작성하는 데 사용되었습니다. 이후 릴리스에서는 이 클래스를 제거할 예정입니다. 대신 KotlinCompilerPluginSupportPlugin 클래스를 사용하십시오.

kotlin.useFallbackCompilerSearch 빌드 옵션과 noReflect 및 includeRuntime 컴파일러 옵션을 제거했습니다. useIR 컴파일러 옵션은 숨겨졌으며 향후 릴리스에서 제거될 예정입니다.

Kotlin Gradle 플러그인에서 현재 지원되는 컴파일러 옵션에 대한 자세한 내용은 Kotlin Gradle 플러그인에서 확인하세요.


표준 라이브러리


표준 라이브러리의 새로운 1.6.0 버전은 실험적인 기능을 안정화하고 새로운 기능을 도입하며 플랫폼 간의 동작을 통일합니다:
 

  • 새로운 readline 함수
  • 안정된 typeOf()
  • 안정된 컬렉션 빌더
  • 안정된 Duration API
  • 정규식을 시퀀스로 분할
  • 정수에 대한 비트 회전 연산
  • JS에서 replace() 및 replaceFirst()에 대한 변경 사항
  • 기존 API 개선
  • 폐기 사항

 

새로운 readline 함수


Kotlin 1.6.0은 표준 입력 처리를 위한 새로운 함수인 readln()과 readlnOrNull()을 제공합니다.

현재 이러한 새 함수는 JVM 및 Native 대상 플랫폼에서만 사용할 수 있습니다.


줄을 읽을 때 !!를 사용하지 않아도 되므로 이 변경 사항은 초보자들에게 더 나은 경험을 제공하고 Kotlin을 가르치기를 간소화할 것으로 기대합니다. read-line 작업 이름을 println()과 일치하게 만들기 위해 새 함수의 이름을 'ln'으로 줄였습니다.

println("별명은 무엇인가요?")
val nickname = readln()
println("안녕, $nickname!")

var sum = 0
while (true) {
    val nextLine = readlnOrNull().takeUnless { 
        it.isNullOrEmpty() 
    } ?: break
    sum += nextLine.toInt()
}
println(sum)


기존의 readLine() 함수는 IDE 코드 완성에서 readln() 및 readlnOrNull()에 비해 낮은 우선 순위를 갖게 됩니다. 또한 IDE 검사에서는 기존의 readLine() 대신 새 함수를 사용하도록 권장합니다. 
 
앞으로의 릴리스에서 gradually readLine() 함수를 퇴화할 계획입니다.


안정된 typeOf()


버전 1.6.0에서 안정된 typeOf() 함수를 제공하여 주요 로드맵 항목 중 하나를 마감합니다.

1.3.40부터 typeOf()은 JVM 플랫폼에서 실험적인 API로 사용할 수 있었습니다. 이제 이 함수를 모든 Kotlin 플랫폼에서 사용할 수 있으며 컴파일러가 추론할 수 있는 모든 Kotlin 타입의 KType 표현을 얻을 수 있습니다.

inline fun <reified T> renderType(): String {
    val type = typeOf<T>()
    return type.toString()
}

fun main() {
    val fromExplicitType = typeOf<Int>()
    val fromReifiedType = renderType<List<Int>>()
}


안정된 collection builders


Kotlin 1.6.0에서 컬렉션 빌더 함수가 안정화되었습니다. 컬렉션 빌더에 의해 반환된 컬렉션은 이제 읽기 전용 상태에서 직렬화됩니다.

이제 opt-in 주석 없이 buildMap(), buildList() 및 buildSet()을 사용할 수 있습니다.

val x = listOf('b', 'c')
val y = buildList {
    add('a')
    addAll(x)
    add('d')
}
println(y)  // [a, b, c, d]


안정된 Duration API


다양한 시간 단위로 지속 시간 양을 나타내는 Duration 클래스가 안정화되었습니다. 1.6.0에서 Duration API는 다음 변경 사항을 받았습니다.

- toComponents() 함수의 첫 번째 구성 요소는 이제 Int 대신 Long 유형을 갖습니다. 이전에는 값이 Int 범위에 들어 맞지 않으면 그 범위로 강제로 변환되었습니다. Long 유형을 사용하면 Int에 맞지 않는 값을 잘라내지 않고 지속 시간 범위 내의 모든 값을 분해할 수 있습니다.
 
- DurationUnit 열거형은 이제 JVM에서는 java.util.concurrent.TimeUnit의 별도이며, typealias DurationUnit = TimeUnit로 사용되지 않습니다. typealias DurationUnit = TimeUnit를 통해 TimeUnit API를 노출하는 것이 DurationUnit 사용자를 혼동시킬 수 있다고 판단하지 않았습니다. 또한 DurationUnit 사용자에게 혼동을 줄 수 있습니다.
 
- 커뮤니티 피드백에 따라 Int.seconds와 같은 확장 프로퍼티를 다시 도입하고 그 적용 범위를 제한하기로 결정했습니다. 이러한 확장 프로퍼티를 Duration 클래스의 companion에 넣었습니다. IDE는 여전히 완성에서 확장을 제안하고 companion에서 자동으로 가져오도록 할 수 있지만 향후에는 Duration 타입이 예상될 때에만 이 동작을 제한하기로 계획하고 있습니다.

val duration = 10000
println("$duration 초에는 ${duration.seconds.inWholeMinutes} 분이 있습니다")
// 10000 초에는 166 분이 있습니다


이전에 도입된 companion 함수(예: Duration.seconds(Int)) 및 Int.seconds와 같은 폐기될 예정인 최상위 확장을 새로운 Duration.Companion의 확장으로 대체하는 것을 제안합니다.

이러한 대체는 이전 최상위 확장과 새로운 companion 확장 간의 모호함을 발생시킬 수 있으므로 자동 마이그레이션을 수행하기 전에 kotlin.time 패키지의 와일드카드 import - import kotlin.time.* -를 사용해야 합니다.


정수의 비트 회전 연산


Kotlin 1.6.0에서 비트 조작을 위한 rotateLeft() 및 rotateRight() 함수가 안정화되었습니다. 이러한 함수는 숫자의 이진 표현을 왼쪽이나 오른쪽으로 지정된 비트 수만큼 회전시킵니다.

val number: Short = 0b10001
println(number
        .rotateRight(2)
        .toString(radix = 2)) // 100000000000100
println(number
        .rotateLeft(2)
        .toString(radix = 2))  // 1000100


JS의 replace() 및 replaceFirst() 변경 사항


이전 Kotlin 1.6.0에서는 replace() 및 replaceFirst() Regex 함수가 대체 문자열이 그룹 참조를 포함하는 경우 Java 및 JS에서 다르게 동작했습니다. 모든 대상 플랫폼에서 동작을 일관되게 만들기 위해 JS에서 이러한 함수의 구현을 변경했습니다.

대체 문자열에 ${name} 또는 $index가 포함된 경우 해당 캡처된 그룹에 해당하는 하위 문자열로 대체됩니다.

- $index: '$' 다음의 첫 번째 숫자는 항상 그룹 참조의 일부로 처리됩니다. 다음 숫자는 유효한 그룹 참조를 형성하는 경우에만 색인에 통합됩니다. '0'부터 '9'까지의 숫자만 그룹 참조의 잠재적인 구성 요소로 간주됩니다. 캡처된 그룹의 인덱스는 '1'부터 시작하며 색인 '0'은 전체 일치를 나타냅니다.

- ${name}: 이름은 라틴 문자 'a'-'z', 'A'-'Z' 또는 숫자 '0'-'9'로 구성될 수 있습니다. 첫 번째 문자는 반드시 문자여야 합니다.

대체 패턴에서의 이름 있는 그룹은 현재 JVM에서만 지원됩니다.

- 대체 문자열을 리터럴 문자열로 처리해야 하는 경우 Regex.escapeReplacement()을 사용할 수 있습니다.
 

println(Regex("(.+)").replace("Kotlin", """\$ $1""")) // $ Kotlin
println(Regex("(.+)").replaceFirst("1.6.0", """\\ $1""")) // \ 1.6.0


기존 API 개선


- 버전 1.6.0에서는 Comparable.compareTo()에 대한 infix 확장 함수를 추가했습니다. 이제 두 객체를 순서대로 비교하는 데 중위 형태를 사용할 수 있습니다.
 

class WrappedText(val text: String) : Comparable<WrappedText> {
     override fun compareTo(other: WrappedText): Int =
         this.text compareTo other.text
}


- JS에서의 Regex.replace()는 이제 더 이상 인라인이 아닌 것으로 통합되어 모든 플랫폼에서의 구현을 일치시킵니다.

- compareTo() 및 equals() 문자열 함수, 그리고 isBlank() CharSequence 함수는 이제 JS에서 JVM과 정확히 같은 방식으로 동작합니다. 이전에는 비 ASCII 문자와 관련하여 차이점이 있었습니다.


폐기 사항



Kotlin 1.6.0에서는 JS 전용 stdlib API 중 일부에 대한 경고와 함께 폐기 주기를 시작합니다.

concat(), match() 및 matches() 문자열 함수
 

  • 주어진 다른 객체의 문자열 표현과 문자열을 연결하려면 concat() 대신 plus()를 사용하십시오.
  • 입력 내에서 정규식의 모든 발생을 찾으려면 String.match(regex: String) 대신 Regex 클래스의 findAll()을 사용하십시오.
  • 정규식이 전체 입력과 일치하는지 확인하려면 String.matches(regex: String) 대신 Regex 클래스의 matches()를 사용하십시오.

 
배열에서의 sort() 및 비교 함수

Array<out T>.sort() 함수와 ByteArray.sort(), ShortArray.sort(), IntArray.sort(), LongArray.sort(), FloatArray.sort(), DoubleArray.sort() 및 CharArray.sort()와 같은 인라인 함수를 폐기했습니다. 이러한 함수는 비교 함수에 전달된 순서대로 배열을 정렬했습니다. 배열 정렬에는 다른 표준 라이브러리 함수를 사용하십시오.

컬렉션 정렬 섹션을 참조하십시오.
 

도구


Kover – Kotlin용 코드 커버리지 도구


Kover Gradle 플러그인은 실험적입니다. GitHub에서의 피드백을 환영합니다.

Kotlin 1.6.0에서는 Kover를 소개합니다. 이는 IntelliJ 및 JaCoCo Kotlin 코드 커버리지 에이전트를 위한 Gradle 플러그인입니다. 이 플러그인은 인라인 함수를 포함한 모든 언어 구조와 함께 작동합니다.

Kover에 대해 더 자세히 알아보려면 해당 GitHub 저장소나 이 비디오를 참조하십시오:
 


Coroutines 1.6.0-RC


kotlinx.coroutines 1.6.0-RC는 다양한 기능과 개선 사항을 갖추고 출시되었습니다:

  • 새로운 Kotlin/Native 메모리 매니저 지원
  • 별도의 스레드를 생성하지 않고 병렬성을 제한하는 디스패처 뷰 API 도입
  • Java 6에서 Java 8 타겟으로 마이그레이션
  • 새로운 리빌드된 API와 멀티플랫폼 지원을 갖춘 kotlinx-coroutines-test
  • 스레드 로컬 변수에 대한 코루틴의 스레드 안전한 쓰기 액세스를 제공하는 CopyableThreadContextElement 도입


변경 내역에서 더 자세히 알아보십시오.


Kotlin 1.6.0으로 마이그레이션


IntelliJ IDEA 및 Android Studio는 Kotlin 플러그인을 1.6.0으로 업데이트하라는 제안을 제공할 것입니다.

기존 프로젝트를 Kotlin 1.6.0으로 마이그레이션하려면 Kotlin 버전을 1.6.0으로 변경하고 Gradle 또는 Maven 프로젝트를 다시 가져오십시오. Kotlin 1.6.0으로 업데이트하는 방법을 알아보려면 Kotlin 1.6.0으로 업데이트하는 방법을 참조하십시오.

Kotlin 1.6.0으로 새 프로젝트를 시작하려면 Kotlin 플러그인을 업데이트하고 파일 | 새로 만들기 | 프로젝트에서 프로젝트 마법사를 실행하십시오.

GitHub 릴리스 페이지에서 새로운 명령줄 컴파일러를 다운로드할 수 있습니다.

Kotlin 1.6.0은 기능 릴리스이므로 언어의 이전 버전용으로 작성된 코드와 호환되지 않을 수 있는 변경 사항을 가져올 수 있습니다. Kotlin 1.6의 호환성 가이드에서 해당 변경 사항의 자세한 목록을 찾을 수 있습니다.
 

원문

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

반응형

댓글