Что нового в Kotlin 1.9.20
Вышел Kotlin 1.9.20: компилятор K2 для всех целевых платформ теперь находится в стадии Beta, а Kotlin Multiplatform теперь имеет статус Stable. Кроме того, вот некоторые из основных нововведений:
Новый шаблон иерархии по умолчанию для настройки мультиплатформенных проектов
Полная поддержка кэша конфигурации Gradle в Kotlin Multiplatform
Пользовательский распределитель памяти включен по умолчанию в Kotlin/Native
Улучшение производительности сборщика мусора в Kotlin/Native
Краткий обзор обновлений также представлен в этом видео:
Поддержка IDE
Плагины Kotlin с поддержкой версии 1.9.20 доступны для следующих IDE:
IDE |
Поддерживаемые версии |
|---|---|
IntelliJ IDEA |
2023.1.x, 2023.2.x, 2023.x |
Android Studio |
Hedgehog (2023.1.1), Iguana (2023.2.1) |
Новые обновления компилятора Kotlin K2
Команда Kotlin в JetBrains продолжает стабилизировать новый компилятор K2, который обеспечит значительное повышение производительности, ускорит разработку новых языковых функций, унифицирует все поддерживаемые Kotlin платформы и предоставит более совершенную архитектуру для мультиплатформенных проектов.
В настоящее время K2 для всех целевых платформ находится в стадии Beta. Подробнее читайте в публикации о выпуске
Поддержка Kotlin/Wasm
Начиная с этого выпуска, Kotlin/Wasm поддерживает новый компилятор K2. Узнайте, как включить его в проекте.
Предварительная версия плагина компилятора kapt с K2
В версии 1.9.20 вы можете попробовать использовать плагин компилятора kapt с компилятором K2. Чтобы использовать компилятор K2 в проекте, добавьте следующие параметры в файл gradle.properties:
kotlin.experimental.tryK2=true kapt.use.k2=true
Кроме того, вы можете включить K2 для kapt, выполнив следующие действия:
В файле
build.gradle.ktsустановите версию языка2.0.В файле
gradle.propertiesдобавьтеkapt.use.k2=true.
Если при использовании kapt с компилятором K2 возникнут проблемы, сообщите о них в наш трекер ошибок.
Как включить компилятор Kotlin K2
Включение K2 в Gradle
Чтобы включить и протестировать компилятор Kotlin K2, используйте новую версию языка со следующим параметром компилятора:
-language-version 2.0
Вы можете указать ее в файле build.gradle.kts:
kotlin {
sourceSets.all {
languageSettings {
languageVersion = "2.0"
}
}
}
Включение K2 в Maven
Чтобы включить и протестировать компилятор Kotlin K2, обновите раздел <project/> в файле pom.xml:
<properties>
<kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion>
</properties>
Включение K2 в IntelliJ IDEA
Чтобы включить и протестировать компилятор Kotlin K2 в IntelliJ IDEA, перейдите в раздел Настройки | Сборка, выполнение, развертывание | Компилятор | Компилятор Kotlin и измените значение поля Версия языка на 2.0 (experimental).
Оставьте отзыв о новом компиляторе K2
Будем рады любым вашим отзывам!
Оставьте отзыв напрямую разработчикам K2 в Kotlin Slack — получите приглашение и присоединитесь к каналу #k2-early-adopters.
Сообщайте о любых проблемах, с которыми вы столкнулись при работе с новым компилятором K2, в наш трекер ошибок.
Включите параметр «Отправлять статистику использования», чтобы разрешить JetBrains собирать анонимные данные об использовании K2.
Kotlin/JVM
Начиная с версии 1.9.20, компилятор может генерировать классы с байт-кодом Java 21.
Kotlin/Native
Kotlin 1.9.20 включает стабильный менеджер памяти с новым распределителем памяти, включенным по умолчанию, улучшения производительности сборщика мусора и другие обновления:
Пользовательский распределитель памяти включен по умолчанию
Kotlin 1.9.20 поставляется с новым распределителем памяти, включенным по умолчанию. Он разработан для замены предыдущего распределителя по умолчанию, mimalloc, повышения эффективности сборки мусора и производительности среды выполнения менеджера памяти Kotlin/Native.
Новый пользовательский распределитель делит системную память на страницы, позволяя независимо выполнять очистку в последовательном порядке. Каждое выделение становится блоком памяти внутри страницы, а страница отслеживает размеры блоков. Разные типы страниц оптимизированы для различных размеров выделений. Последовательное расположение блоков памяти обеспечивает эффективный перебор всех выделенных блоков.
При выделении памяти поток ищет подходящую страницу в зависимости от размера выделения. Потоки поддерживают набор страниц для разных категорий размеров. Как правило, текущая страница для заданного размера может вместить выделение. В противном случае поток запрашивает другую страницу из общего пространства выделения. Такая страница может уже быть доступна, требовать очистки или ее потребуется сначала создать.
Новый распределитель позволяет одновременно использовать несколько независимых пространств выделения, что даст команде Kotlin возможность экспериментировать с различными макетами страниц, чтобы еще больше повысить производительность.
Как включить пользовательский распределитель памяти
Начиная с Kotlin 1.9.20, новый распределитель памяти используется по умолчанию. Дополнительная настройка не требуется.
Если вы столкнулись с высоким потреблением памяти, можно переключиться обратно на mimalloc или системный распределитель, указав -Xallocator=mimalloc или -Xallocator=std в скрипте сборки Gradle. Сообщайте о таких проблемах в YouTrack, чтобы помочь нам улучшить новый распределитель памяти.
Технические подробности о конструкции нового распределителя см. в этом файле README.
Улучшение производительности сборщика мусора
Команда Kotlin продолжает повышать производительность и стабильность нового менеджера памяти Kotlin/Native. В этом выпуске появилось несколько значительных изменений в сборщике мусора (GC), в том числе следующие ключевые нововведения версии 1.9.20:
Полная параллельная разметка для сокращения времени паузы GC
Отслеживание памяти большими блоками для повышения производительности выделения
Полная параллельная разметка для сокращения времени паузы GC
Ранее сборщик мусора по умолчанию выполнял только частичную параллельную разметку. Когда поток-мутатор приостанавливался, он начинал разметку GC со своих корней, таких как локальные переменные потока и стек вызовов. В это время отдельный поток GC отвечал за разметку, начиная с глобальных корней, а также с корней всех мутирующих потоков, которые активно выполняли нативный код и поэтому не были приостановлены.
Такой подход хорошо работал в случаях, когда число глобальных объектов было ограничено, а мутирующие потоки значительную часть времени находились в состоянии готовности, выполняя код Kotlin. Однако это не относится к типичным приложениям для iOS.
Теперь GC использует полную параллельную разметку, объединяющую приостановленные мутирующие потоки, поток GC и необязательные потоки-разметчики для обработки очереди разметки. По умолчанию разметку выполняют:
Приостановленные мутирующие потоки. Вместо обработки собственных корней с последующим простоем в периоды, когда они не выполняют код, они участвуют во всем процессе разметки.
Поток GC. Это гарантирует, что разметку будет выполнять как минимум один поток.
Новый подход делает процесс разметки эффективнее, сокращая время паузы GC.
Отслеживание памяти большими блоками для повышения производительности выделения
Ранее планировщик GC отслеживал выделение каждого объекта по отдельности. Однако ни новый пользовательский распределитель по умолчанию, ни распределитель памяти mimalloc не выделяют отдельное хранилище для каждого объекта: они выделяют большие области сразу для нескольких объектов.
В Kotlin 1.9.20 GC отслеживает области, а не отдельные объекты. Это ускоряет выделение небольших объектов, уменьшая количество операций, выполняемых при каждом выделении, и тем самым помогает минимизировать использование памяти сборщиком мусора.
Инкрементальная компиляция артефактов klib
В Kotlin 1.9.20 появилась новая оптимизация времени компиляции для Kotlin/Native. Компиляция артефактов klib в нативный код теперь частично выполняется инкрементально.
При компиляции исходного кода Kotlin в нативный бинарный файл в режиме отладки компиляция проходит в два этапа:
Исходный код компилируется в артефакты
klib.Артефакты
klibвместе с зависимостями компилируются в бинарный файл.
Для оптимизации времени компиляции на втором этапе команда уже реализовала кэши компилятора для зависимостей. Они компилируются в нативный код только один раз, а результат повторно используется при каждой компиляции бинарного файла. Однако артефакты klib, созданные из исходных файлов проекта, при каждом изменении проекта всегда полностью перекомпилировались в нативный код.
При новой инкрементальной компиляции, если изменение модуля проекта приводит к частичной перекомпиляции исходного кода в артефакты klib, в бинарный файл затем перекомпилируется только часть klib.
Чтобы включить инкрементальную компиляцию, добавьте следующий параметр в файл gradle.properties:
kotlin.incremental.native=true
Если вы столкнулись с проблемами, сообщите о них в YouTrack.
Управление проблемами связывания библиотек
В этом выпуске улучшен способ обработки компилятором Kotlin/Native проблем связывания в библиотеках Kotlin. Сообщения об ошибках теперь содержат более понятные объявления: вместо хешей в них используются имена сигнатур, что помогает проще находить и устранять проблемы. Пример:
No function found for symbol 'org.samples/MyClass.removedFunction|removedFunction(kotlin.Int;kotlin.String){}[0]'
Компилятор Kotlin/Native обнаруживает проблемы связывания между сторонними библиотеками Kotlin и сообщает об ошибках во время выполнения. Такие проблемы могут возникнуть, если автор одной сторонней библиотеки Kotlin внесет несовместимое изменение в экспериментальные API, которые использует другая сторонняя библиотека Kotlin.
Начиная с Kotlin 1.9.20, компилятор по умолчанию обнаруживает проблемы связывания в беззвучном режиме. Вы можете изменить эту настройку в своих проектах:
Чтобы записывать эти проблемы в журналы компиляции, включите предупреждения с помощью параметра компилятора
-Xpartial-linkage-loglevel=WARNING.Также можно повысить уровень серьезности предупреждений до ошибок компиляции с помощью
-Xpartial-linkage-loglevel=ERROR. В этом случае компиляция завершается с ошибкой, а журнал компиляции содержит все ошибки. Используйте этот параметр, чтобы подробнее изучить проблемы связывания.
// An example of passing compiler options in a Gradle build file:
kotlin {
macosX64("native") {
binaries.executable()
compilations.configureEach {
compilerOptions.configure {
// To report linkage issues as warnings:
freeCompilerArgs.add("-Xpartial-linkage-loglevel=WARNING")
// To raise linkage warnings to errors:
freeCompilerArgs.add("-Xpartial-linkage-loglevel=ERROR")
}
}
}
}
Если с этой функцией возникнут неожиданные проблемы, вы всегда можете отказаться от ее использования с помощью параметра компилятора -Xpartial-linkage=disable. Не стесняйтесь сообщать о таких случаях в наш трекер ошибок.
Инициализация companion-объекта при вызове конструктора класса
Начиная с Kotlin 1.9.20, бэкенд Kotlin/Native вызывает статические инициализаторы для companion-объектов в конструкторах классов:
class Greeting {
companion object {
init {
print("Hello, Kotlin!")
}
}
}
fun main() {
val start = Greeting() // Prints "Hello, Kotlin!"
}
Теперь поведение унифицировано с Kotlin/JVM, где companion-объект инициализируется при загрузке (разрешении) соответствующего класса, что соответствует семантике статического инициализатора Java.
Теперь, когда реализация этой функции стала согласованнее между платформами, делиться кодом в мультиплатформенных проектах Kotlin стало проще.
Необходимость явного согласия для всех объявлений cinterop
Начиная с Kotlin 1.9.20, все объявления Kotlin, сгенерированные инструментом cinterop из библиотек C и Objective-C, таких как libcurl и libxml, помечаются аннотацией @ExperimentalForeignApi. Если аннотация для явного согласия отсутствует, ваш код не скомпилируется.
Это требование отражает экспериментальный статус импорта библиотек C и Objective-C. Рекомендуем ограничить его использование отдельными областями проектов. Это упростит переход после того, как мы начнем стабилизировать импорт.
Пользовательское сообщение об ошибках компоновщика
Если вы автор библиотеки, теперь вы можете помочь пользователям устранить ошибки компоновщика, добавив пользовательские сообщения.
Если ваша библиотека Kotlin зависит от библиотек C или Objective-C, например, при использовании интеграции с CocoaPods, пользователям необходимо иметь эти зависимые библиотеки на компьютере или явно настроить их в скрипте сборки проекта. Если это условие не выполнялось, пользователи получали непонятное сообщение «Framework not found».
Теперь вы можете указать конкретную инструкцию или ссылку в сообщении об ошибке компиляции. Для этого передайте параметр компилятора -Xuser-setup-hint в cinterop или добавьте свойство userSetupHint=message в файл .def.
Удаление устаревшего менеджера памяти
Новый менеджер памяти появился в Kotlin 1.6.20 и стал использоваться по умолчанию в версии 1.7.20. С тех пор он продолжал получать обновления и улучшения производительности и приобрел статус Stable.
Пришло время завершить цикл устаревания и удалить устаревший менеджер памяти. Если вы все еще используете его, удалите параметр kotlin.native.binary.memoryModel=strict из файла gradle.properties и внесите необходимые изменения, следуя нашему руководству по миграции.
Изменение политики уровней поддержки целевых платформ
Мы решили повысить требования для поддержки первого уровня. Теперь команда Kotlin обязуется обеспечивать совместимость исходного и бинарного кода между выпусками компилятора для целевых платформ, соответствующих критериям первого уровня. Кроме того, такие платформы должны регулярно тестироваться с помощью инструментов CI, чтобы обеспечить возможность компиляции и запуска. В настоящее время к первому уровню относятся следующие целевые платформы для узлов macOS:
macosX64macosArm64iosSimulatorArm64iosX64
В Kotlin 1.9.20 мы также удалили ряд целевых платформ, поддержка которых ранее была объявлена устаревшей, а именно:
iosArm32watchosX86wasm32mingwX86linuxMips32linuxMipsel32
Полный список поддерживаемых целевых платформ см. здесь.
Kotlin Multiplatform
В Kotlin 1.9.20 основное внимание уделено стабилизации Kotlin Multiplatform, а также дальнейшему улучшению опыта разработчиков благодаря новым мастерам создания проектов и другим важным функциям:
Упрощенная настройка новых версий стандартной библиотеки в Gradle
Поддержка кэшей компиляции Kotlin/Native в проектах Compose Multiplatform
Kotlin Multiplatform — стабильная версия
Выпуск 1.9.20 стал важной вехой в развитии Kotlin: Kotlin Multiplatform наконец стал стабильным. Это означает, что эту технологию безопасно использовать в ваших проектах и она на 100% готова к промышленной эксплуатации. Кроме того, дальнейшая разработка Kotlin Multiplatform будет вестись в соответствии с нашими строгими правилами обратной совместимости.
Обратите внимание: некоторые расширенные возможности Kotlin Multiplatform все еще развиваются. При их использовании вы получите предупреждение с описанием текущего статуса стабильности соответствующей функции. Прежде чем использовать экспериментальные функции в IntelliJ IDEA,
необходимо явно включить их в разделе Настройки | Дополнительные настройки | Kotlin | Экспериментальные возможности Multiplatform.
Посетите блог Kotlin, чтобы узнать больше о стабилизации Kotlin Multiplatform и планах на будущее.
Ознакомьтесь с руководством по совместимости Multiplatform, чтобы узнать о значительных изменениях, внесенных в ходе стабилизации.
Прочитайте о механизме ожидаемых и фактических объявлений — важной части Kotlin Multiplatform, которая также была частично стабилизирована в этом выпуске.
Шаблон настройки многоплатформенных проектов
Начиная с Kotlin 1.9.20 плагин Kotlin Gradle автоматически создает общие исходные наборы для популярных сценариев Multiplatform. Если ваш проект относится к одному из них, настраивать иерархию исходных наборов вручную не нужно. Просто явно укажите необходимые для проекта целевые платформы.
Теперь настройка стала проще благодаря шаблону иерархии по умолчанию — новой функции плагина Kotlin Gradle. Это встроенный в плагин предварительно заданный шаблон иерархии исходных наборов. Он содержит промежуточные исходные наборы, которые Kotlin автоматически создает для указанных вами целевых платформ. Посмотреть полный шаблон.
Упростите создание проекта
Рассмотрим многоплатформенный проект, предназначенный для устройств Android и iPhone и разрабатываемый на MacBook с Apple Silicon. Сравним настройку этого проекта в разных версиях Kotlin:
Kotlin 1.9.0 и более ранние версии (стандартная настройка) |
Kotlin 1.9.20 |
|---|---|
kotlin {
androidTarget()
iosArm64()
iosSimulatorArm64()
sourceSets {
val commonMain by getting
val iosMain by creating {
dependsOn(commonMain)
}
val iosArm64Main by getting {
dependsOn(iosMain)
}
val iosSimulatorArm64Main by getting {
dependsOn(iosMain)
}
}
}
|
kotlin {
androidTarget()
iosArm64()
iosSimulatorArm64()
// The iosMain source set is created automatically
}
|
Обратите внимание, что использование шаблона иерархии по умолчанию значительно сокращает объем шаблонного кода, необходимого для настройки проекта.
Когда в коде объявлены целевые платформы androidTarget, iosArm64 и iosSimulatorArm64, плагин Kotlin Gradle находит подходящие общие исходные наборы в шаблоне и создает их. Полученная иерархия выглядит так:
Зеленые исходные наборы действительно создаются и включаются в проект, а серые наборы из шаблона по умолчанию игнорируются.
Использование автодополнения для исходных наборов
Чтобы упростить работу с созданной структурой проекта, IntelliJ IDEA теперь предлагает автодополнение для исходных наборов, созданных с помощью шаблона иерархии по умолчанию:

Kotlin также предупредит вас, если вы попытаетесь обратиться к исходному набору, которого не существует, поскольку соответствующая целевая платформа не объявлена. В примере ниже отсутствует целевая платформа JVM (есть только androidTarget, что не одно и то же). Но давайте попробуем использовать исходный набор jvmMain и посмотрим, что произойдет:
kotlin {
androidTarget()
iosArm64()
iosSimulatorArm64()
sourceSets {
jvmMain {
}
}
}
В этом случае Kotlin выведет предупреждение в журнале сборки:
w: Accessed 'source set jvmMain' without registering the jvm target:
kotlin {
jvm() /* <- register the 'jvm' target */
sourceSets.jvmMain.dependencies {
}
}
Настройка иерархии целевых платформ
Начиная с Kotlin 1.9.20 шаблон иерархии по умолчанию включен автоматически. В большинстве случаев дополнительная настройка не требуется.
Однако при переносе существующих проектов, созданных до версии 1.9.20, вы можете столкнуться с предупреждением, если ранее вручную добавляли промежуточные исходные наборы с помощью вызовов dependsOn(). Чтобы решить эту проблему, выполните следующие действия:
-
Если ваши промежуточные исходные наборы уже охватываются шаблоном иерархии по умолчанию, удалите все вызовы
dependsOn(), добавленные вручную, а также исходные наборы, созданные с помощью конструкцийby creating.Полный список исходных наборов по умолчанию см. в шаблоне иерархии.
-
Если вам нужны дополнительные исходные наборы, отсутствующие в шаблоне иерархии по умолчанию, например набор для совместного использования кода целевыми платформами macOS и JVM, скорректируйте иерархию, явно применив шаблон повторно с помощью
applyDefaultHierarchyTemplate(), а затем настройте дополнительные исходные наборы вручную, как обычно, используяdependsOn():kotlin { jvm() macosArm64() iosArm64() iosSimulatorArm64() // Apply the default hierarchy explicitly. It'll create, for example, the iosMain source set: applyDefaultHierarchyTemplate() sourceSets { // Create an additional jvmAndMacos source set val jvmAndMacos by creating { dependsOn(commonMain.get()) } macosArm64Main.get().dependsOn(jvmAndMacos) jvmMain.get().dependsOn(jvmAndMacos) } } -
Если в проекте уже есть исходные наборы с теми же именами, что и у наборов, создаваемых шаблоном, но они совместно используются другими наборами целевых платформ, изменить связи
dependsOnпо умолчанию между исходными наборами шаблона сейчас невозможно.В этом случае можно выбрать другие исходные наборы для своих задач — из шаблона иерархии по умолчанию или созданные вручную. Другой вариант — полностью отказаться от шаблона.
Чтобы отказаться от шаблона, добавьте
kotlin.mpp.applyDefaultHierarchyTemplate=falseвgradle.propertiesи настройте все остальные исходные наборы вручную.Сейчас мы работаем над API для создания собственных шаблонов иерархии, чтобы упростить настройку в подобных случаях.
Полный шаблон иерархии
Когда вы объявляете целевые платформы, для которых компилируется проект, плагин выбирает из шаблона соответствующие общие исходные наборы и создает их в проекте.
Новый мастер создания проектов
Команда JetBrains представляет новый способ создания кроссплатформенных проектов — веб-мастер Kotlin Multiplatform.
Первая версия нового мастера Kotlin Multiplatform охватывает наиболее популярные сценарии использования Kotlin Multiplatform. В ней учтены все отзывы о предыдущих шаблонах проектов, а архитектура сделана максимально надежной и устойчивой.
Новый мастер имеет распределенную архитектуру, которая позволяет использовать единую серверную часть и разные интерфейсы. Первым шагом стала веб-версия. В будущем мы рассматриваем возможность создания версии для IDE и инструмента командной строки. Веб-версия всегда предоставляет самую актуальную версию мастера, а в IDE придется дождаться следующего выпуска.
С новым мастером настроить проект проще, чем когда-либо. Вы можете адаптировать проекты под свои потребности, выбрав целевые платформы для мобильной, серверной и настольной разработки. В будущих выпусках мы также планируем добавить поддержку веб-разработки.

Теперь новый мастер создания проектов — рекомендуемый способ создания кроссплатформенных проектов на Kotlin. Начиная с версии 1.9.20 плагин Kotlin больше не предоставляет мастер проекта Kotlin Multiplatform в IntelliJ IDEA.
Новый мастер поможет легко выполнить первоначальную настройку и значительно упростит процесс начала работы. Если возникнут проблемы, сообщите о них в YouTrack, чтобы помочь нам улучшить работу мастера.
Полная поддержка кэша конфигурации Gradle в Kotlin Multiplatform
Ранее мы представили предварительную версию кэша конфигурации Gradle, доступную для библиотек Kotlin Multiplatform. В версии 1.9.20 плагин Kotlin Multiplatform делает еще один шаг вперед.
Теперь кэш конфигурации Gradle поддерживается плагином Kotlin CocoaPods Gradle, а также задачами интеграции, необходимыми для сборок Xcode, например embedAndSignAppleFrameworkForXcode.
Теперь все многоплатформенные проекты могут воспользоваться улучшением времени сборки. Кэш конфигурации Gradle ускоряет процесс сборки, повторно используя результаты этапа конфигурации при последующих сборках. Дополнительные сведения и инструкции по настройке см. в документации Gradle.
Упрощенная настройка новых версий стандартной библиотеки в Gradle
При создании многоплатформенного проекта зависимость от стандартной библиотеки (stdlib) автоматически добавляется в каждый исходный набор. Это самый простой способ начать работу с многоплатформенными проектами.
Ранее, чтобы настроить зависимость от стандартной библиотеки вручную, требовалось задавать ее отдельно для каждого исходного набора. Начиная с версии kotlin-stdlib:1.9.20, зависимость достаточно настроить один раз в корневом исходном наборе commonMain:
Версия стандартной библиотеки 1.9.10 и более ранние версии |
Версия стандартной библиотеки 1.9.20 |
|---|---|
kotlin {
sourceSets {
// For the common source set
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10")
}
}
// For the JVM source set
val jvmMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.10")
}
}
// For the JS source set
val jsMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-js:1.9.10")
}
}
}
}
|
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
}
}
}
}
|
Это изменение стало возможным благодаря добавлению новой информации в метаданные Gradle стандартной библиотеки. Благодаря этому Gradle автоматически определяет подходящие артефакты стандартной библиотеки для остальных исходных наборов.
Поддержка сторонних библиотек cinterop по умолчанию
В Kotlin 1.9.20 добавлена поддержка по умолчанию (вместо поддержки, включаемой по запросу) всех зависимостей cinterop в проектах, где применяется плагин Kotlin CocoaPods Gradle.
Это означает, что теперь можно использовать больше общего нативного кода без ограничений, связанных с платформенными зависимостями. Например, можно добавить зависимости от библиотек Pod в общий исходный набор iosMain.
Ранее это работало только с платформенными библиотеками, поставляемыми с дистрибутивом Kotlin/Native (например, Foundation, UIKit и POSIX). Теперь все сторонние библиотеки Pod доступны в общих исходных наборах по умолчанию. Указывать отдельное свойство Gradle для их поддержки больше не нужно.
Поддержка кэшей компиляции Kotlin/Native в проектах Compose Multiplatform
В этом выпуске устранена проблема совместимости с плагином компилятора Compose Multiplatform, которая в основном затрагивала проекты Compose Multiplatform для iOS.
Чтобы обойти эту проблему, приходилось отключать кэширование с помощью свойства Gradle kotlin.native.cacheKind=none. Однако это обходное решение снижало производительность: компиляция замедлялась, поскольку в компиляторе Kotlin/Native не работало кэширование.
Теперь, когда проблема устранена, можно удалить kotlin.native.cacheKind=none из файла gradle.properties и ускорить компиляцию проектов Compose Multiplatform.
Дополнительные советы по ускорению компиляции см. в документации Kotlin/Native.
Рекомендации по совместимости
При настройке проектов проверьте совместимость плагина Kotlin Multiplatform Gradle с доступными версиями Gradle, Xcode и Android Gradle plugin (AGP):
Плагин Kotlin Multiplatform Gradle |
Gradle |
Android Gradle plugin |
Xcode |
|---|---|---|---|
1.9.20 |
7.5 и более поздние версии |
7.4.2–8.2 |
15.0. См. подробности ниже |
В этом выпуске рекомендуется использовать Xcode версии 15.0. Библиотеки, поставляемые с Xcode 15.0, полностью поддерживаются, и обращаться к ним можно из любого места кода Kotlin.
Однако Xcode 14.3 по-прежнему должен работать в большинстве случаев. Имейте в виду, что если на локальном компьютере установлена версия 14.3, библиотеки, поставляемые с Xcode 15, будут видны, но недоступны.
Kotlin/Wasm
В версии 1.9.20 Kotlin Wasm достиг уровня Alpha стабильности.
Совместимость с этапом 4 Wasm GC и окончательными кодами операций
Новая целевая платформа
wasm-wasiи переименование целевой платформыwasmвwasm-js
Совместимость с этапом 4 Wasm GC и окончательными кодами операций
Wasm GC переходит к заключительному этапу, для которого требуется обновить коды операций — числовые константы, используемые в двоичном представлении. Kotlin 1.9.20 поддерживает новейшие коды операций, поэтому мы настоятельно рекомендуем обновить проекты Wasm до последней версии Kotlin. Также рекомендуем использовать последние версии браузеров со средой Wasm:
Версия 119 или новее для Chrome и браузеров на основе Chromium.
Версия 119 или новее для Firefox. Обратите внимание: в Firefox 119 необходимо включить Wasm GC вручную.
Новая целевая платформа wasm-wasi и переименование wasm в wasm-js
В этом выпуске мы представляем новую целевую платформу для Kotlin/Wasm — wasm-wasi. Также мы переименовываем целевую платформу wasm в wasm-js. В DSL Gradle эти целевые платформы доступны как wasmWasi {} и wasmJs {} соответственно.
Чтобы использовать эти целевые платформы в проекте, обновите файл build.gradle.kts:
kotlin {
wasmWasi {
// ...
}
wasmJs {
// ...
}
}
Ранее представленный блок wasm {} объявлен устаревшим и заменен на wasmJs {}.
Чтобы перенести существующий проект Kotlin/Wasm, выполните следующие действия:
В файле
build.gradle.ktsпереименуйте блокwasm {}вwasmJs {}.В структуре проекта переименуйте каталог
wasmMainвwasmJsMain.
Поддержка API WASI в стандартной библиотеке
В этом выпуске добавлена поддержка WASI — системного интерфейса для платформы Wasm. Поддержка WASI позволяет легче использовать Kotlin/Wasm вне браузеров, например в серверных приложениях, благодаря стандартизированному набору API для доступа к системным ресурсам. Кроме того, WASI обеспечивает безопасность на основе возможностей — дополнительный уровень защиты при обращении к внешним ресурсам.
Для запуска приложений Kotlin/Wasm нужна виртуальная машина с поддержкой сборки мусора Wasm (GC), например Node.js или Deno. Wasmtime, WasmEdge и другие среды продолжают работу над полной поддержкой Wasm GC.
Чтобы импортировать функцию WASI, используйте аннотацию @WasmImport:
import kotlin.wasm.WasmImport
@WasmImport("wasi_snapshot_preview1", "clock_time_get")
private external fun wasiRawClockTimeGet(clockId: Int, precision: Long, resultPtr: Int): Int
Улучшения API Kotlin/Wasm
В этом выпуске добавлено несколько улучшений API Kotlin/Wasm, упрощающих повседневную работу. Например, теперь для обработчиков событий DOM не требуется возвращать значение:
До версии 1.9.20 |
В версии 1.9.20 |
|---|---|
fun main() {
window.onload = {
document.body?.sayHello()
null
}
}
|
fun main() {
window.onload = { document.body?.sayHello() }
}
|
Gradle
Kotlin 1.9.20 полностью совместим с Gradle версий от 6.8.3 до 8.1. Также можно использовать версии Gradle вплоть до самой последней, но в этом случае могут появиться предупреждения об устаревших функциях или некоторые новые возможности Gradle могут работать некорректно.
В этой версии представлены следующие изменения:
Поддержка доступа тестовых фикстур к внутренним объявлениям
В Kotlin 1.9.20, если вы используете плагин Gradle java-test-fixtures, ваши тестовые фикстуры теперь имеют доступ к объявлениям internal в классах основного исходного набора. Кроме того, любые исходные файлы тестов могут обращаться к объявлениям internal в классах тестовых фикстур.
Новое свойство для настройки путей к каталогам Konan
В Kotlin 1.9.20 доступно свойство Gradle konan.data.dir, позволяющее настроить путь к каталогу ~/.konan без необходимости задавать его с помощью переменной среды KONAN_DATA_DIR.
Также можно использовать параметр компилятора -Xkonan-data-dir, чтобы настроить собственный путь к каталогу ~/.konan с помощью инструментов cinterop и konanc.
Новые метрики задач Kotlin/Native в отчетах о сборке
В Kotlin 1.9.20 отчеты о сборке Gradle теперь содержат метрики для задач Kotlin/Native. Пример отчета о сборке с этими метриками:
Total time for Kotlin tasks: 20.81 s (93.1 % of all tasks time)
Time |% of Kotlin time|Task
15.24 s|73.2 % |:compileCommonMainKotlinMetadata
5.57 s |26.8 % |:compileNativeMainKotlinMetadata
Task ':compileCommonMainKotlinMetadata' finished in 15.24 s
Task info:
Kotlin language version: 2.0
Time metrics:
Total Gradle task time: 15.24 s
Spent time before task action: 0.16 s
Task action before worker execution: 0.21 s
Run native in process: 2.70 s
Run entry point: 2.64 s
Size metrics:
Start time of task action: 2023-07-27T11:04:17
Task ':compileNativeMainKotlinMetadata' finished in 5.57 s
Task info:
Kotlin language version: 2.0
Time metrics:
Total Gradle task time: 5.57 s
Spent time before task action: 0.04 s
Task action before worker execution: 0.02 s
Run native in process: 1.48 s
Run entry point: 1.47 s
Size metrics:
Start time of task action: 2023-07-27T11:04:32
Кроме того, отчет о сборке kotlin.experimental.tryK2 теперь включает все скомпилированные задачи Kotlin/Native и указывает использованную версию языка:
##### 'kotlin.experimental.tryK2' results ##### :lib:compileCommonMainKotlinMetadata: 2.0 language version :lib:compileKotlinJvm: 2.0 language version :lib:compileKotlinIosArm64: 2.0 language version :lib:compileKotlinIosSimulatorArm64: 2.0 language version :lib:compileKotlinLinuxX64: 2.0 language version :lib:compileTestKotlinJvm: 2.0 language version :lib:compileTestKotlinIosSimulatorArm64: 2.0 language version :lib:compileTestKotlinLinuxX64: 2.0 language version ##### 100% (8/8) tasks have been compiled with Kotlin 2.0 #####
Стандартная библиотека
В Kotlin 1.9.20 стандартная библиотека Kotlin/Native становится стабильной, а также появляются новые возможности:
Замена обобщённой функции values класса Enum
В Kotlin 1.9.0 свойство entries для классов-перечислений получило статус стабильного. Свойство entries — это современная и производительная замена синтетической функции values(). В Kotlin 1.9.20 появилась замена обобщённой функции enumValues<T>(): enumEntries<T>().
Например:
enum class RGB { RED, GREEN, BLUE }
@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T : Enum<T>> printAllValues() {
print(enumEntries<T>().joinToString { it.name })
}
printAllValues<RGB>()
// RED, GREEN, BLUE
Как включить функцию enumEntries
Чтобы опробовать эту возможность, явно согласитесь на её использование с помощью @OptIn(ExperimentalStdlibApi) и используйте версию языка 1.9 или выше. Если вы используете последнюю версию плагина Kotlin Gradle, указывать версию языка для проверки этой возможности не нужно.
Стандартная библиотека Kotlin/Native становится стабильной
В Kotlin 1.9.0 мы рассказали о мерах, которые приняли, чтобы приблизить стандартную библиотеку Kotlin/Native к цели — сделать её стабильной. В Kotlin 1.9.20 мы наконец завершаем эту работу и присваиваем стандартной библиотеке Kotlin/Native стабильный статус. Вот некоторые важные изменения в этом выпуске:
Класс
Vector128перемещён из пакетаkotlin.nativeв пакетkotlinx.cinterop.Уровень требования явного согласия на использование аннотаций
ExperimentalNativeApiиNativeRuntimeApi, появившихся в Kotlin 1.9.0, повышен сWARNINGдоERROR.Коллекции Kotlin/Native теперь обнаруживают параллельные модификации, например, в коллекциях
ArrayListиHashMap.-
Функция
printStackTrace()классаThrowableтеперь выводит данные вSTDERRвместоSTDOUT.
Улучшения API Atomics
В Kotlin 1.9.0 мы сообщили, что API Atomics будет готов получить стабильный статус одновременно со стандартной библиотекой Kotlin/Native. В Kotlin 1.9.20 появились следующие дополнительные изменения:
-
Добавлены экспериментальные классы
AtomicIntArray,AtomicLongArrayиAtomicArray<T>. Эти новые классы созданы специально для соответствия атомарным массивам Java, чтобы в будущем их можно было включить в общую стандартную библиотеку. В пакете
kotlin.native.concurrentдля API Atomics, устаревшего в Kotlin 1.9.0 с уровнем устареванияWARNING, уровень устаревания повышен доERROR.В пакете
kotlin.concurrentудалены функции-члены классовAtomicIntиAtomicLong, уровень устаревания которых составлялERROR.Все функции-члены класса
AtomicReferenceтеперь используют атомарные intrinsic-функции.
Дополнительные сведения обо всех изменениях в Kotlin 1.9.20 см. в нашей задаче в YouTrack.
Повышение производительности операций HashMap в Kotlin/JS
В Kotlin 1.9.20 повышена производительность операций HashMap и уменьшен объём занимаемой ими памяти в Kotlin/JS. Внутренняя реализация Kotlin/JS была изменена на метод открытой адресации. Благодаря этому производительность должна повыситься при выполнении следующих операций:
Добавление новых элементов в
HashMap.Поиск существующих элементов в
HashMap.Перебор ключей или значений в
HashMap.
Обновления документации
В документацию Kotlin внесены следующие важные изменения:
Справочник API JVM Metadata — узнайте, как анализировать метаданные с помощью Kotlin/JVM.
Руководство по измерению времени — узнайте, как вычислять и измерять время в Kotlin.
Обновлённая глава о коллекциях в интерактивном курсе по Kotlin — изучите основы языка программирования Kotlin в главах, сочетающих теорию и практику.
Определённо ненулевые типы — узнайте об обобщённых типах, которые определённо не допускают значения null.
Обновлённая страница «Массивы» — узнайте о массивах и о том, когда их использовать.
Ожидаемые и фактические объявления в Kotlin Multiplatform — узнайте о механизме Kotlin для ожидаемых и фактических объявлений в Kotlin Multiplatform.
Установка Kotlin 1.9.20
Проверьте версию IDE
IntelliJ IDEA 2023.1.x и 2023.2.x автоматически предложат обновить плагин Kotlin до версии 1.9.20. В IntelliJ IDEA 2023.3 будет включён плагин Kotlin 1.9.20.
Android Studio Hedgehog (231) и Iguana (232) будут поддерживать Kotlin 1.9.20 в предстоящих выпусках.
Новый компилятор командной строки можно скачать на странице выпуска на GitHub.
Настройка Gradle
Чтобы загружать артефакты и зависимости Kotlin, обновите файл settings.gradle(.kts), указав репозиторий Maven Central:
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}
Если репозиторий не указан, Gradle использует закрытый репозиторий JCenter, что может привести к проблемам с артефактами Kotlin.
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew1920.html