Releases

Kotlin 1.6.20 출시

Read this post in other languages:

Kotlin 1.6.20이 공식 출시되었습니다. 향후 언어 기능의 테스트 버전을 제공하고, 계층 구조를 멀티플랫폼 프로젝트의 디폴트 값으로 설정하며, JVM, JS 및 Native 플랫폼의 성능을 개선합니다.

이 블로그 글에서는 다음 개선 사항에 대한 개요와 더불어 다른 점진적 변경 사항에 대한 전체 목록을 확인할 수 있습니다.


업데이트 방법

IntelliJ IDEA 또는 Android Studio를 사용하는 경우, 새로운 Kotlin 릴리스가 출시되는 즉시 자동으로 업데이트할 수 있는 옵션이 제공됩니다.

Kotlin 1.6.20으로 업데이트

주요 업데이트

Kotlin/JVM용 컨텍스트 리시버 프로토타입

Kotlin 1.6.20에서는 리시버 개수가 하나로 제한되지 않습니다. 더 많이 필요한 경우 선언에 컨텍스트 리시버를 추가하여 함수, 프로퍼티 및 클래스를 컨텍스트 의존적으로(혹은 컨텍스트 기반) 만들면 됩니다. 컨텍스트 기반 선언은 다음과 같습니다.

  • 모든 선언된 컨텍스트 리시버가 호출자의 범위에서 묵시적 리시버로 있어야 합니다.
  • 선언된 컨텍스트 리시버를 본문 범위에 묵시적인 리시버로 가져옵니다.

프로젝트에서 컨텍스트 리시버를 활성화하려면, -Xcontext-receivers 컴파일러 옵션을 사용하세요. 이 기능 및 구문의 자세한 설명은 KEEP에서 확인할 수 있습니다.

이번 구현은 프로토타입인 점에 유의하세요. 

  • -Xcontext-receivers가 활성화된 상태에서 컴파일러는 프로덕션 코드에서 사용할 수 없는 사전 릴리스 바이너리를 생성합니다. 
  • 현재 IDE는 컨텍스트 리시버를 최소한의 수준으로 지원합니다.

확정적으로 null 가능하지 않은 타입

제네릭 Java 클래스 및 인터페이스를 확장할 때 상호 운용성을 개선하기 위해 Kotlin 1.6.20에서는 제네릭 타입 매개변수를 T & Any가 사용되는 곳에서 확정적으로 null 가능하지 않은 타입으로 표시할 수 있습니다. 구문 형태는 교차 타입 표기에서 온 것이며 이제 &의 왼쪽에 있는 null 가능 상한선과 오른쪽의 null 가능하지 않은 Any를 가진 타입 매개변수로 제한됩니다.

기능을 활성화하려면 언어 버전을 1.7로 설정하세요.

KEEP에서 확정적으로 null 가능하지 않은 타입에 대해서 더 알아보세요.

현재 확정적으로 null 가능하지 않은 타입은 베타입니다. 거의 안정화가 되었지만 추후에 마이그레이션 과정이 필요할 수도 있습니다. 변경 사항을 최소화하기 위해 노력하겠습니다.

JVM IR 백엔드에서 하나의 모듈에 대한 병렬 컴파일 지원

Kotlin 1.6.20에서 하나의 모듈에 있는 모든 파일을 병렬로 컴파일하는 실험적인 기능인 JVM IR 백엔드 모드를 추가하였습니다. 병렬 컴파일은 총 컴파일 시간을 최대 15%까지 줄일 수 있습니다.

compiler option -Xbackend-threads로 실험적 병렬 백엔드 모드를 활성화하세요. 이 옵션에 다음의 인수를 사용하세요.

  • N은 사용하고 싶은 스레드의 수입니다. CPU 코어 수를 초과해서는 안됩니다. 초과하는 경우 컨텍스트가 스레드 간에 전환되어 효율적으로 병렬화되지 않습니다.
  • 0으로 CPU 코어당 1개 스레드를 사용

Gradle은 작업을 병렬로 실행할 수 있지만, Gradle의 관점에서 프로젝트(혹은 프로젝트의 주요한 부분)가 하나의 큰 작업일 뿐일 때는 이러한 병렬화가 별로 도움되지 않습니다. 매우 큰 모놀리식 모듈이 있는 경우 병렬 컴파일을 사용하여 더 빠르게 컴파일하세요. 프로젝트가 다수의 작은 모듈로 구성되어 있으며 빌드가 Gradle로 병렬화되어 있는 경우 병렬화 레이어를 추가하면 컨텍스트 전환으로 인해 성능에 나쁜 영향을 줄 수 있습니다.

병렬 컴파일에는 일부 제약이 있습니다.

  • kapt는 IR 백엔드를 비활성화하기 때문에 kapt와는 사용할 수 없습니다.
  • 설계상 JVM 힙이 더 필요합니다. 필요한 heap의 양은 스레드 수에 비례합니다.

Kotlin/JS IR 컴파일러를 사용하는 개발 바이너리에서 증분 컴파일 지원

IR 컴파일러를 활용한 Kotlin/JS 개발을 더욱 효율화하기 위해 증분 컴파일 모드를 도입했습니다.

이 모드에서 compileDevelopmentExecutableKotlinJs Gradle 작업이 있는 개발 바이너리를 빌드할 때는 컴파일러가 모듈 수준에서 이전 컴파일의 결과를 캐시에 저장합니다. 이어지는 컴파일에서 변경 사항이 없는 소스 파일에 캐시된 컴파일 결과를 사용하므로, 특히 변경 사항이 적을 때 컴파일 완료 속도가 빨라집니다. 이 개선 사항은 개발 프로세스에만 적용되며(편집-빌드-디버그 사이클 단축) 프로덕션 아티팩트 빌드에는 영향을 주지 않습니다.

개발 바이너리의 증분 컴파일을 활성화하려면, 다음 줄을 프로젝트의 gradle.properties에 추가하세요.

테스트 프로젝트에서 새로운 모드를 사용할 경우 증분 컴파일이 최대 30% 빨랐습니다. 그러나 이 모드에서 클린 빌드는 캐시를 생성하고 준비해야 하기 때문에 더 느렸습니다.

Kotlin/Native 성능 개선

Kotlin 1.6.20에는 Koltin이 생성하는 LLVM IR에 영향을 주는 성능 업데이트와 버그 수정이 일부 포함되었습니다. 저희가 내부 프로젝트에서 벤치마크를 실행한 결과에 따르면 평균 성능 향상은 다음과 같았습니다.

  • 실행 시간 15% 감소
  • 릴리스 및 디버그 바이너리의 코드 크기 20% 감소
  • 릴리스 바이너리의 컴파일 시간 26% 감소

이번 변경으로 대규모 내부 프로젝트에서 디버그 바이너리의 컴파일 시간도 10% 감소했습니다.

이러한 결과를 얻기 위해 컴파일러가 생성한 일부 통합 객체의 정적 초기화를 구현하고, 모든 함수에 대해 LLVM IR을 구조화하는 방법을 개선하였으며, 컴파일러 캐시를 최적화했습니다.

멀티 플랫폼 프로젝트에서 계층적 구조 지원

Kotlin 1.6.20에는 계층적 구조 지원이 기본적으로 활성화되어 있습니다. Kotlin 1.4.0에서 이 기능을 도입한 이후 프런트엔드를 크게 개선하였으며 IDE 가져오기를 안정화했습니다.

이전에 멀티플랫폼 프로젝트에서 코드를 추가하는 방법은 두 가지였습니다. 첫 번째는 특정 플랫폼용, 즉 하나의 대상 플랫폼 외에 다른 플랫폼에서는 사용할 수 없는 소스 세트에 코드를 추가하는 방법이었습니다. 두 번째는 Kotlin에서 현재 지원하는 모든 플랫폼에서 공유되는 공통 소스 세트를 사용하는 방법입니다.

이제는 공통 로직과 타사 API를 많이 재사용하는 여러 개의 유사한 네이티브 대상에서 소스 코드를 공유할 수 있습니다. 이 기술은 정확한 디폴트 종속성을 제공하며 공유된 코드에서 사용할 수 있는 정확한 API를 찾아줍니다. 이에 따라 복잡한 빌드 설정이 필요 없고, 여러 네이티브 대상에서 코드 세트를 공유할 수 있는 IDE 지원을 얻기 위해 해결책을 사용할 필요도 없어졌습니다. 또한, 다른 대상에 사용해야 할 API를 안전하지 않게 사용하는 경우도 방지할 수 있습니다.

이 기술은 라이브러리 작성자에게도 편리합니다. 계층적 프로젝트 구조가 지원되면 대상의 하위 세트에서 쓸 수 있는 공통 API로 라이브러리를 게시하고 사용할 수 있기 때문입니다.
기본적으로 계층적 프로젝트 구조로 게시된 라이브러리는 계층적 구조의 프로젝트와만 호환됩니다. 프로젝트 및 라이브러리 호환성에 대해 자세히 알아보세요.

개선된 프로젝트 내 코드 공유

계층적 구조가 지원되지 않으면 일부 Kotlin 대상 간에 코드를 공유할 수는 있어도 모든 대상 간에 쉽게 공유할 방법은 없습니다. 대표적인 예시는 모든 iOS 대상에서 코드를 공유하면서 Foundation과 같은 iOS용 종속성에 액세스하는 것입니다.

이제 계층적 프로젝트 구조가 지원되므로 별도 설정 없이 이를 바로 실현할 수 있습니다. 새로운 구조에서 소스 세트는 계층 구조를 형성합니다. 소스 세트가 컴파일되는 각 대상에서 지원되는 플랫폼용 언어 기능과 종속성을 사용할 수 있습니다.

iOS 기기 및 시뮬레이터용으로 iosArm64iosX64라는 2개의 대상을 가진 일반적 멀티플랫폼 프로젝트를 예시로 들어 보겠습니다. Kotlin 도구는 두 대상 모두 같은 함수를 갖고 있다는 것을 인지하며 사용자가 중간 소스 세트인 iosMain의 함수에 액세스할 수 있게 합니다.

Kotlin 툴체인은 Kotlin/Native stdlib 혹은 네이티브 라이브러리 같은 올바른 디폴트 종속성을 제공합니다. 또한 Kotlin 도구는 공유된 코드에서 이용할 수 있는 API 서피스 영역을 정확히 찾기 위해 노력합니다. 이는 Windows에 공유되는 코드에 macOS용 함수가 사용되는 것과 같은 사례를 방지합니다.

라이브러리 작성자에게 더 많은 기회

이제 멀티플랫폼 라이브러리가 게시되면, 중간 소스 세트의 API가 함께 적절히 게시되어 소비자들이 사용할 수 있게 됩니다. Kotlin 툴체인이 소비자 소스 세트에서 사용할 수 있는 API를 자동으로 파악하며, JS 코드에서 JVM용 API를 사용하는 것과 같은 안전하지 않은 사용을 감시합니다. 라이브러리에서 코드를 공유하는 방법에 대해 자세히 알아보세요.

구성 및 설정

Kotlin 1.6.20부터 모든 신규 멀티플랫폼 프로젝트는 계층적 프로젝트 구조를 갖게 됩니다. 추가적인 설정이 필요하지 않습니다.

  • 이미 수동으로 켠 경우 gradle.properties에서 지원 중단된 옵션을 제거할 수 있습니다.
  • 사용자 경험을 최적화하기 위해 Kotlin 1.6.20에는 Android Studio 2021.1.1(Bumblebee) 혹은 이후 버전을 사용하는 것이 좋습니다.
  • 이 기능을 선택 해제할 수도 있습니다. 계층적 구조 지원을 비활성화하려면, gradle.properties에서 다음의 옵션을 설정하세요.

개선점 전체 목록

언어

Kotlin/JVM

Kotlin/Native

Kotlin 멀티플랫폼

Kotlin/JS

보안

Gradle

Kotlin 1.6.20 설치 방법

이미 IntelliJ IDEA 또는 Android Studio를 사용하고 있는 경우 IDE에서 자동으로 Kotlin을 1.6.20으로 업데이트할 것을 제안합니다. 또한 이 지침을 따라 직접 업데이트할 수도 있습니다. 

다음 IDE의 최신 버전을 다운로드하여 광범위한 Kotlin 지원을 받을 수 있습니다.

  • IntelliJ IDEA – 다양한 플랫폼 용 Kotlin 애플리케이션 개발을 지원
  • Android Studio –  Android 및 크로스 플랫폼 모바일 애플리케이션 개발 지원

또한 kotlinx 라이브러리를 호환되는 버전으로 업데이트하고 기존 프로젝트의 빌드 스크립트에 Kotlin 버전 1.6.20을 지정했는지 확인하세요.

명령줄 컴파일러가 필요한 경우, Github 릴리스 페이지에서 다운로드하세요.

문제가 발생한 경우

최신 Kotlin 기능에 대한 최신 정보를 받아보세요! 이 게시물의 오른쪽에 있는 양식을 작성하시면 Kotlin 업데이트를 받아보실 수 있습니다.

기타 유용한 글과 영상

게시물 원문 작성자

Jessie Cho

Andrey Polyakov

image description

Discover more