Spec-Zone.ru › Kotlin 1.9

Что нового в Kotlin 1.9.0

Дата выпуска: 6 июля 2023 года

Вышла версия Kotlin 1.9.0, и компилятор K2 для JVM теперь в бета-версии. Кроме того, вот некоторые ключевые моменты:

  • Новые обновления компилятора Kotlin K2

  • Стабильная замена функции enum class values

  • Стабильный ..< оператор для открытых диапазонов

  • Новая общая функция для получения группы захвата регулярного выражения по имени

  • Новая утилита для создания родительских каталогов

  • Предварительный просмотр кеша конфигурации Gradle в Kotlin Multiplatform

  • Изменения в поддержке целей Android в Kotlin Multiplatform

  • Предварительный просмотр пользовательского аллокатора памяти в Kotlin/Native

  • Связывание библиотек в Kotlin/Native

  • Оптимизации, связанные с размером, в Kotlin/Wasm

Вы также можете найти краткий обзор обновлений в этом видео:

Поддержка IDE

Плагины Kotlin, поддерживающие 1.9.0, доступны для:

IDE

Поддерживаемые версии

IntelliJ IDEA

2022.3.x, 2023.1.x

Android Studio

Giraffe (223), Hedgehog (231)*

*Плагин Kotlin 1.9.0 будет включен в Android Studio Giraffe (223) и Hedgehog (231) в ближайших выпусках.

Плагин Kotlin 1.9.0 будет включен в IntelliJ IDEA 2023.2 в ближайших выпусках.

Для загрузки артефактов и зависимостей Kotlin, настройте параметры Gradle, чтобы использовать Maven Central Repository.

Новые обновления компилятора Kotlin K2

Команда Kotlin в JetBrains продолжает стабилизировать компилятор K2, и выпуск 1.9.0 содержит дальнейшие улучшения. Компилятор K2 для JVM теперь в бета-версии.

Теперь также есть базовая поддержка проектов Kotlin/Native и многоплатформенных проектов.

Совместимость плагина kapt компилятора с компилятором K2

Вы можете использовать плагин kapt в вашем проекте вместе с компилятором K2, но с некоторыми ограничениями. Несмотря на установку languageVersion в 2.0, плагин kapt компилятора по-прежнему использует старый компилятор.

Если вы выполните плагин kapt компилятора в проекте, где languageVersion установлено в 2.0, kapt автоматически переключится на 1.9 и отключит проверки совместимости определённых версий. Это поведение эквивалентно включению следующих командных аргументов:

  • -Xskip-metadata-version-check

  • -Xskip-prerelease-check

  • -Xallow-unstable-dependencies

Эти проверки отключены исключительно для задач kapt. Все остальные задачи компиляции будут продолжать использовать новый компилятор K2.

Если у вас возникнут проблемы при использовании kapt с компилятором K2, сообщите об этом в нашем отслеживании проблем.

Попробуйте компилятор K2 в вашем проекте

Начиная с версии 1.9.0 и до выпуска Kotlin 2.0, вы можете легко протестировать компилятор K2 с помощью свойства Gradle kotlin.experimental.tryK2=true. Вы также можете выполнить следующую команду:

./gradlew assemble -Pkotlin.experimental.tryK2=true

Это свойство Gradle автоматически устанавливает версию языка на 2.0 и обновляет отчет о сборке с количеством задач Kotlin, скомпилированных с помощью компилятора K2 по сравнению с текущим компилятором:

##### 'kotlin.experimental.tryK2' results (Kotlin/Native not checked) #####
:lib:compileKotlin: 2.0 language version
:app:compileKotlin: 2.0 language version
##### 100% (2/2) tasks have been compiled with Kotlin 2.0 #####

Отчеты о сборке Gradle

Отчеты о сборке Gradle теперь показывают, был ли использован текущий или компилятор K2 для компиляции кода. В Kotlin 1.9.0 вы можете увидеть эту информацию в ваших отчётах о сборке Gradle:

Gradle build scan - K1
Gradle build scan - K2

Вы также можете найти используемую версию Kotlin в отчёте о сборке:

Task info:
  Kotlin language version: 1.9

Если вы используете Gradle 8.0, у вас могут возникнуть проблемы с отчётами о сборке, особенно при включённом кешировании конфигурации Gradle. Это известная проблема, исправленная в Gradle 8.1 и более поздних версиях.

Ограничения текущего компилятора K2

Включение K2 в ваш проект Gradle имеет некоторые ограничения, которые могут повлиять на проекты, использующие версии Gradle ниже 8.3 в следующих случаях:

  • Компиляция исходного кода из buildSrc.

  • Компиляция плагинов Gradle во включённых сборках.

  • Компиляция других плагинов Gradle, если они используются в проектах с версиями Gradle ниже 8.3.

  • Сборка зависимостей плагина Gradle.

Если вы столкнулись с какой-либо из вышеперечисленных проблем, вы можете предпринять следующие шаги для их решения:

  • Установите версию языка для buildSrc, любых плагинов Gradle и их зависимостей:

kotlin {
    compilerOptions {
        languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9)
        apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9)
    }
}
  • Обновите версию Gradle в вашем проекте до 8.3, когда она станет доступна.

Оставьте свой отзыв о новом компиляторе K2

Мы будем признательны за любой ваш отзыв!

  • Поделитесь своим отзывом напрямую разработчикам K2 в Slack Kotlin – получите приглашение и присоединитесь к каналу #k2-early-adopters.

  • Сообщите о любых проблемах, с которыми вы столкнулись при использовании нового компилятора K2, в нашем отслеживании проблем.

  • Включите опцию Отправка статистических данных о использовании, чтобы разрешить JetBrains собирать анонимные данные об использовании K2.

Язык

В Kotlin 1.9.0 мы стабилизировали некоторые новые возможности языка, которые были введены ранее:

  • Замена функции enum class values

  • Симметрия объектов данных с классами данных

  • Поддержка вторичных конструкторов с телами в инлайновых классах значений

Стабильная замена функции enum class values

В 1.8.20 свойство entries для классов перечислений было введено как экспериментальная функция. Свойство entries является современной и эффективной заменой для синтетической функции values(). В 1.9.0 свойство entries является стабильным.

Функция values() по-прежнему поддерживается, но мы рекомендуем использовать свойство entries вместо неё.

enum class Color(val colorName: String, val rgb: String) {
    RED("Red", "#FF0000"),
    ORANGE("Orange", "#FF7F00"),
    YELLOW("Yellow", "#FFFF00")
}

fun findByRgb(rgb: String): Color? = Color.entries.find { it.rgb == rgb }

Дополнительную информацию о свойстве entries для классов перечислений см. в Новом в Kotlin 1.8.20.

Стабильные объекты данных для симметрии с классами данных

Объявления объектов данных, которые были введены в Kotlin 1.8.20, теперь являются стабильными. Это включает функции, добавленные для симметрии с классами данных: toString(), equals(), и hashCode().

Эта функция особенно полезна с sealed иерархиями (например, sealed class или sealed interface), потому что объявления data object удобно использовать вместе с объявлениями data class. В этом примере объявление EndOfFile в качестве data object вместо простого object означает, что у него автоматически есть функция toString() без необходимости ручного переопределения. Это поддерживает симметрию с сопутствующими определениями класса данных.

sealed interface ReadResult
data class Number(val number: Int) : ReadResult
data class Text(val text: String) : ReadResult
data object EndOfFile : ReadResult

fun main() {
    println(Number(7)) // Number(number=7)
    println(EndOfFile) // EndOfFile
}

Дополнительную информацию см. в Новом в Kotlin 1.8.20.

Поддержка вторичных конструкторов с телами в инлайновых классах значений

Начиная с Kotlin 1.9.0, использование вторичных конструкторов с телами в инлайновых классах значений доступно по умолчанию:

@JvmInline
value class Person(private val fullName: String) {
    // Allowed since Kotlin 1.4.30:
    init {
        check(fullName.isNotBlank()) {
            "Full name shouldn't be empty"
        }
    }
    // Allowed by default since Kotlin 1.9.0:
    constructor(name: String, lastName: String) : this("$name $lastName") {
        check(lastName.isNotBlank()) {
            "Last name shouldn't be empty"
        }
    }
}

Ранее Kotlin допускал только публичные первичные конструкторы в инлайновых классах. В результате было невозможно инкапсулировать основополагающие значения или создать инлайновый класс, который бы представлял некоторые ограниченные значения.

По мере развития Kotlin эти проблемы были решены. Kotlin 1.4.30 снял ограничения на блоки init, а затем Kotlin 1.8.20 представил предварительный просмотр вторичных конструкторов с телами. Они теперь доступны по умолчанию. Подробнее об эволюции инлайновых классов Kotlin см. в этом KEEP.

Kotlin/JVM

Начиная с версии 1.9.0, компилятор может генерировать классы с версией байт-кода, соответствующей JVM 20. Кроме того, продолжается устаревание аннотации JvmDefault и устаревших -Xjvm-default режимов.

Устаревание аннотации JvmDefault и устаревших режимов -Xjvm-default

Начиная с Kotlin 1.5, использование аннотации JvmDefault устарело в пользу новых режимов -Xjvm-default: all и all-compatibility С введением JvmDefaultWithoutCompatibility в Kotlin 1.4 и JvmDefaultWithCompatibility в Kotlin 1.6, эти режимы предлагают комплексный контроль над генерацией классов DefaultImpls, гарантируя бесшовную совместимость со старым кодом Kotlin.

Следовательно, в Kotlin 1.9.0 аннотация JvmDefault больше не имеет значения и была помечена как устаревшая, что приведет к ошибке. В конечном счете, она будет удалена из Kotlin.

Kotlin/Native

В этом релизе, помимо прочих улучшений, внесены дальнейшие усовершенствования в менеджер памяти Kotlin/Native, которые должны повысить его надёжность и производительность:

  • Предварительный просмотр пользовательского менеджера памяти

  • Обработчик удаления объекта Objective-C или Swift в главном потоке

  • Отсутствие инициализации объектов при обращении к константным значениям в Kotlin/Native

  • Возможность настроить автономный режим для тестов iOS-симулятора

  • Связывание библиотек в Kotlin/Native

Предварительный просмотр пользовательского менеджера памяти

Kotlin 1.9.0 представляет предварительный просмотр пользовательского менеджера памяти. Его система выделения памяти улучшает производительность во время выполнения менеджера памяти Kotlin/Native.

Текущая система выделения объектов в Kotlin/Native использует универсальный менеджер памяти, который не имеет функций для эффективного сбора мусора. Для компенсации он поддерживает локальные для потока списки всех выделенных объектов до объединения их сборщиком мусора (GC) в единый список, который можно перебирать во время очистки. Этот подход имеет несколько недостатков с точки зрения производительности:

  • Порядок очистки не имеет локальности памяти и часто приводит к разбросанным шаблонам доступа к памяти, что может привести к проблемам производительности.

  • Связанные списки требуют дополнительной памяти для каждого объекта, увеличивая использование памяти, особенно при работе с множеством небольших объектов.

  • Единый список выделенных объектов затрудняет распараллеливание очистки, что может вызвать проблемы с использованием памяти, когда потоки выделения объектов работают быстрее, чем поток GC может их собирать.

Для решения этих проблем Kotlin 1.9.0 представляет предварительный просмотр пользовательского менеджера памяти. Он делит системную память на страницы, позволяя независимую очистку в последовательном порядке. Каждое выделение становится блоком памяти на странице, а страница отслеживает размер блоков. Разные типы страниц оптимизированы для различных размеров выделения. Последовательная организация блоков памяти обеспечивает эффективную итерацию по всем выделенным блокам.

Когда поток выделяет память, он ищет подходящую страницу на основе размера выделения. Потоки поддерживают набор страниц для разных категорий размеров. Обычно текущая страница для данного размера может вместить выделение. Если нет, поток запрашивает другую страницу из общего пространства выделения. Эта страница может быть уже доступна, требует очистки или должна быть создана.

Новый менеджер памяти позволяет иметь несколько независимых пространств выделения одновременно, что позволит команде Kotlin экспериментировать с различными макетами страниц, чтобы ещё больше улучшить производительность.

Для получения дополнительной информации о проектировании нового менеджера памяти см. этот README.

Как включить

Добавьте параметр компилятора -Xallocator=custom.

kotlin {
    macosX64("native") {
        binaries.executable()

        compilations.configureEach {
            compilerOptions.configure {
                freeCompilerArgs.add("-Xallocator=custom")
            }
        }
    }
}

Оставьте отзыв

Мы будем рады получить ваш отзыв в YouTrack, чтобы улучшить пользовательский менеджер памяти.

Обработчик удаления объекта Objective-C или Swift в главном потоке

Начиная с Kotlin 1.9.0, обработчик удаления объекта Objective-C или Swift вызывается в главном потоке, если объект передан в Kotlin там. Способ, которым менеджер памяти Kotlin/Native ранее обрабатывал ссылки на объекты Objective-C, мог приводить к утечкам памяти. Мы считаем, что новое поведение должно улучшить надёжность менеджера памяти.

Рассмотрим объект Objective-C, на который есть ссылка в коде Kotlin, например, когда он передаётся в качестве аргумента, возвращается функцией или извлекается из коллекции. В этом случае Kotlin создаёт свой собственный объект, содержащий ссылку на объект Objective-C. Когда объект Kotlin удаляется, среда выполнения Kotlin/Native вызывает функцию objc_release, которая освобождает ссылку на объект Objective-C.

Ранее менеджер памяти Kotlin/Native выполнял objc_release в специальном потоке GC. Если это последняя ссылка на объект, объект удаляется. Проблемы могут возникнуть, когда у объектов Objective-C есть пользовательские обработчики удаления, такие как метод dealloc в Objective-C или блок deinit в Swift, и эти обработчики ожидают вызова в определённом потоке.

Поскольку обработчики объектов в главном потоке обычно ожидают вызова именно там, среда выполнения Kotlin/Native теперь также вызывает objc_release в главном потоке. Это должно охватить случаи, когда объект Objective-C был передан в Kotlin в главном потоке, создавая там объект-эквивалент Kotlin. Это работает только если обрабатывается главная очередь диспетчеризации, что происходит в обычных приложениях с пользовательским интерфейсом. Когда это не главная очередь, или объект был передан в Kotlin в потоке, отличном от главного, objc_release вызывается в специальном потоке GC, как и раньше.

Как отказаться

В случае возникновения проблем можно отключить это поведение в вашем файле gradle.properties с помощью следующего параметра:

kotlin.native.binary.objcDisposeOnMain=false

Не стесняйтесь сообщать такие случаи в нашем трекере проблем.

Отсутствие инициализации объектов при обращении к константным значениям в Kotlin/Native

Начиная с Kotlin 1.9.0, бэкенд Kotlin/Native не инициализирует объекты при обращении к полям const val.

object MyObject {
    init {
        println("side effect!")
    }

    const val y = 1
}

fun main() {
    println(MyObject.y) // No initialization at first
    val x = MyObject    // Initialization occurs
    println(x.y)
}

Это поведение теперь унифицировано с Kotlin/JVM, где реализация согласуется с Java, и объекты в этом случае никогда не инициализируются. Вы также можете ожидать некоторых улучшений производительности в ваших проектах Kotlin/Native благодаря этому изменению.

Возможность настроить автономный режим для тестов iOS-симулятора в Kotlin/Native

По умолчанию при запуске тестов iOS-симулятора для Kotlin/Native используется флаг --standalone, чтобы избежать ручного запуска и выключения симулятора. В 1.9.0 вы теперь можете настроить использование этого флага в задаче Gradle через свойство standalone. По умолчанию используется флаг --standalone, поэтому автономный режим включён.

Вот пример того, как отключить автономный режим в вашем файле build.gradle.kts.

tasks.withType<org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest>().configureEach {
    standalone.set(false)
}

Если вы отключите автономный режим, вам необходимо будет запустить симулятор вручную. Чтобы запустить симулятор из командной строки, вы можете использовать следующую команду:

/usr/bin/xcrun simctl boot <DeviceId>

Связывание библиотек в Kotlin/Native

Начиная с Kotlin 1.9.0, компилятор Kotlin/Native обрабатывает проблемы со связью в Kotlin-библиотеках так же, как и Kotlin/JVM. Такие проблемы могут возникнуть, если автор одной сторонней Kotlin-библиотеки внесёт несовместимое изменение в экспериментальные API, которые потребляет другая сторонная Kotlin-библиотека.

Теперь сборка не завершается ошибкой при компиляции в случае проблем со связью между сторонними Kotlin-библиотеками. Вместо этого вы столкнётесь с этими ошибками только во время выполнения, точно так же, как и на JVM.

Компилятор Kotlin/Native сообщает предупреждения всякий раз, когда обнаруживает проблемы со связью библиотек. Вы можете найти такие предупреждения в своих логах компиляции, например:

No function found for symbol 'org.samples/MyRemovedClass.doSomething|3657632771909858561[0]'

Can not get instance of singleton 'MyEnumClass.REMOVED_ENTRY': No enum entry found for symbol 'org.samples/MyEnumClass.REMOVED_ENTRY|null[0]'

Function 'getMyRemovedClass' can not be called: Function uses unlinked class symbol 'org.samples/MyRemovedClass|null[0]'

Вы можете дополнительно настроить или даже отключить это поведение в своих проектах:

  • Если вы не хотите видеть эти предупреждения в своих логах компиляции, подавите их с помощью параметра компилятора -Xpartial-linkage-loglevel=INFO.

  • Также можно повысить уровень серьёзности сообщённых предупреждений до ошибок компиляции с помощью -Xpartial-linkage-loglevel=ERROR. В этом случае компиляция завершается с ошибкой, и все ошибки будут отображены в логе компиляции. Используйте этот параметр для более детального анализа проблем со связью.

  • Если вы столкнётесь с непредвиденными проблемами с этой функцией, всегда можете отказаться от неё с помощью параметра компилятора -Xpartial-linkage=disable . Не стесняйтесь сообщать такие случаи в нашем трекере проблем.

// An example of passing compiler options via Gradle build file.
kotlin {
    macosX64("native") {
        binaries.executable()

        compilations.configureEach {
            compilerOptions.configure {

                // To suppress linkage warnings:
                freeCompilerArgs.add("-Xpartial-linkage-loglevel=INFO")

                // To raise linkage warnings to errors:
                freeCompilerArgs.add("-Xpartial-linkage-loglevel=ERROR")

                // To disable the feature completely:
                freeCompilerArgs.add("-Xpartial-linkage=disable")
            }
        }
    }
}

Параметр компилятора для неявных преобразований целых чисел при C-взаимодействии

Продолжая работу над стабилизацией Kotlin/Native, мы представили параметр компилятора для C-взаимодействия, который позволяет использовать неявные преобразования целых чисел. Ранее настройка параметра компилятора для неявных преобразований целых чисел не требовалась. После тщательного рассмотрения мы ввели этот параметр компилятора, чтобы предотвратить непреднамеренное использование, поскольку данная функция всё ещё нуждается в доработке, и нашей целью является создание API наивысшего качества.

В этом примере кода неявное преобразование целых чисел позволяет options = 0 , несмотря на то, что options имеет тип без знака UInt , а 0 — со знаком.

val today = NSDate()
val tomorrow = NSCalendar.currentCalendar.dateByAddingUnit(
    unit = NSCalendarUnitDay,
    value = 1,
    toDate = today,
    options = 0
)

Чтобы использовать неявные преобразования с библиотеками нативного взаимодействия, используйте параметр компилятора -XXLanguage:+ImplicitSignedToUnsignedIntegerConversion.

Вы можете настроить это в вашем файле Gradle build.gradle.kts:

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile>().configureEach {
    compilerOptions.freeCompilerArgs.addAll(
        "-XXLanguage:+ImplicitSignedToUnsignedIntegerConversion"
    )
}

Kotlin Многоплатформенность

Kotlin Многоплатформенность получила ряд значительных обновлений в версии 1.9.0, призванных улучшить ваш опыт разработки:

  • Изменения в поддержке платформы Android

  • Новая структура наборов исходных файлов Android по умолчанию

  • Предварительный просмотр кэша конфигурации Gradle в многоплатформенных проектах

Изменения в поддержке платформы Android

Мы продолжаем работу по стабилизации Kotlin Многоплатформенность. Важным шагом является обеспечение первоклассной поддержки платформы Android. Мы рады объявить, что в будущем команда Android из Google предоставит свой собственный плагин Gradle для поддержки Android в Kotlin Многоплатформенность.

Чтобы открыть путь для этого нового решения от Google, мы переименовали блок android в текущем Kotlin DSL в версии 1.9.0. Пожалуйста, замените все вхождения блока android на androidTarget в ваших скриптах сборки. Это временное изменение, необходимое для освобождения имени android для предстоящего DSL от Google.

Плагин Google станет предпочтительным способом работы с Android в многоплатформенных проектах. Когда он будет готов, мы предоставим необходимые инструкции по миграции, чтобы вы могли использовать краткое имя android как и прежде.

Новая структура наборов исходных файлов Android по умолчанию

Начиная с Kotlin 1.9.0, новая структура наборов исходных файлов Android установлена по умолчанию. Она заменила предыдущую схему именования каталогов, которая была неоднозначной. Новая структура имеет ряд преимуществ:

  • Упрощенная семантика типов — Новая структура наборов исходных файлов Android обеспечивает ясные и согласованные соглашения об именовании, которые помогают различать различные типы наборов исходных файлов.

  • Улучшенная структура каталогов исходных файлов — С новой структурой расположение SourceDirectories становится более согласованным, что упрощает организацию кода и поиск исходных файлов.

  • Ясная схема именования конфигураций Gradle — Схема стала более согласованной и предсказуемой как в KotlinSourceSets, так и в AndroidSourceSets.

Новая структура требует версии плагина Android Gradle 7.0 или выше и поддерживается в Android Studio 2022.3 и более поздних версиях. Обратитесь к нашему руководству по миграции, чтобы внести необходимые изменения в ваш файл build.gradle(.kts).

Предварительный просмотр кэша конфигурации Gradle

Kotlin 1.9.0 включает поддержку кэша конфигурации Gradle в многоплатформенных библиотеках. Если вы являетесь автором библиотеки, вы уже можете получить выгоду от улучшенной производительности сборки.

Кэш конфигурации Gradle ускоряет процесс сборки, повторно используя результаты фазы конфигурации для последующих сборок. Функция стала стабильной начиная с Gradle 8.1. Чтобы включить её, следуйте инструкциям в документации Gradle.

Плагин Kotlin Многоплатформенность всё ещё не поддерживает кэш конфигурации Gradle с задачами интеграции Xcode или плагином Gradle для Kotlin CocoaPods. Мы ожидаем добавить эту функцию в будущие версии Kotlin.

Kotlin/Wasm

Команда Kotlin продолжает экспериментировать с новым целевым вариантом Kotlin/Wasm. Этот выпуск включает несколько оптимизаций производительности и оптимизаций размера, а также обновления в взаимодействии с JavaScript.

Оптимизации размера

Kotlin 1.9.0 вносит существенные улучшения в размер проектов WebAssembly (Wasm). Сравнивая два проекта «Hello World», занимаемый объем кода Wasm в Kotlin 1.9.0 теперь более чем в 10 раз меньше, чем в Kotlin 1.8.20.

Kotlin/Wasm size-related optimizations

Эти оптимизации размера приводят к более эффективному использованию ресурсов и улучшенной производительности при использовании Kotlin-кода для платформ Wasm.

Обновления в взаимодействии с JavaScript

Это обновление Kotlin вносит изменения во взаимодействие между Kotlin и JavaScript для Kotlin/Wasm. Так как Kotlin/Wasm является экспериментальной функцией, на его взаимодействие накладываются определённые ограничения.

Ограничение динамических типов

Начиная с версии 1.9.0, Kotlin больше не поддерживает использование типов Dynamic в Kotlin/Wasm. Теперь они устарели в пользу нового универсального типа JsAny, который облегчает взаимодействие с JavaScript.

Для получения более подробной информации см. документацию по взаимодействию Kotlin/Wasm с JavaScript.

Ограничение типов, не являющихся внешними

Kotlin/Wasm поддерживает преобразования для определённых статических типов Kotlin при передаче значений в JavaScript и из него. Эти поддерживаемые типы включают:

  • Примитивные типы, такие как числа со знаком, Boolean, и Char.

  • String.

  • Типы функций.

Другие типы передавались без преобразования как неявные ссылки, что приводило к несоответствиям между JavaScript и Kotlin-подтипированием.

Для решения этой проблемы Kotlin ограничивает взаимодействие с JavaScript набором хорошо поддерживаемых типов. Начиная с Kotlin 1.9.0, в Kotlin/Wasm взаимодействии с JavaScript поддерживаются только внешние, примитивные, строковые и функциональные типы. Кроме того, был введен отдельный явный тип JsReference, представляющий ссылки на объекты Kotlin/Wasm, которые могут использоваться в JavaScript-взаимодействии.

Для получения более подробной информации, обратитесь к документации по взаимодействию Kotlin/Wasm с JavaScript.

Kotlin/Wasm в Kotlin Playground

Kotlin Playground поддерживает целевой вариант Kotlin/Wasm. Вы можете писать, запускать и делиться своим Kotlin-кодом, нацеленным на Kotlin/Wasm. Попробуйте!

Использование Kotlin/Wasm требует включения экспериментальных функций в вашем браузере.

Узнайте больше о том, как включить эти функции.

import kotlin.time.*
import kotlin.time.measureTime

fun main() {
    println("Hello from Kotlin/Wasm!")
    computeAck(3, 10)
}

tailrec fun ack(m: Int, n: Int): Int = when {
    m == 0 -> n + 1
    n == 0 -> ack(m - 1, 1)
    else -> ack(m - 1, ack(m, n - 1))
}

fun computeAck(m: Int, n: Int) {
    var res = 0
    val t = measureTime {
        res = ack(m, n)
    }
    println()
    println("ack($m, $n) = ${res}")
    println("duration: ${t.inWholeNanoseconds / 1e6} ms")
}

Kotlin/JS

В этом релизе представлены обновления для Kotlin/JS, включая устаревание плагина Kotlin/JS Gradle и экспериментальную поддержку ES6:

  • Устаревание плагина Kotlin/JS Gradle

  • Устаревание внешних перечислений

  • Экспериментальная поддержка ES6 классов и модулей

  • Изменение целевого каталога для JS-распределения (производство)

  • Извлечение объявлений org.w3c из stdlib-js

Начиная с версии 1.9.0, также включена частичная компоновка библиотек для Kotlin/JS.

Устаревание плагина Kotlin/JS Gradle

Начиная с Kotlin 1.9.0, плагин kotlin-js Gradle устарел. Рекомендуется использовать плагин kotlin-multiplatform Gradle с целевым параметром js().

Функциональность плагина Kotlin/JS Gradle в основном дублировала плагин kotlin-multiplatform и использовала одну и ту же реализацию внутри. Это дублирование создавало путаницу и увеличивало нагрузку на команду Kotlin по сопровождению.

Обратитесь к нашему руководству по совместимости Kotlin Multiplatform за инструкциями по миграции. Если вы обнаружите проблемы, которые не охвачены в руководстве, сообщите об этом в нашем трекере ошибок.

Устаревание внешних перечислений

В Kotlin 1.9.0 использование внешних перечислений будет устаревшим из-за проблем со статическими членами перечислений, такими как entries, которые не могут существовать вне Kotlin. Рекомендуется использовать вместо этого внешние запечатанные классы с подклассами типа object:

// Before
external enum class ExternalEnum { A, B }

// After
external sealed class ExternalEnum {
    object A: ExternalEnum
    object B: ExternalEnum
}

Переход на внешний запечатанный класс с подклассами типа object позволит добиться сходной функциональности внешних перечислений, избежав проблем, связанных с методами по умолчанию.

Начиная с Kotlin 1.9.0, использование внешних перечислений будет помечено как устаревшее. Рекомендуется обновить код для использования предлагаемой реализации внешнего запечатанного класса для совместимости и последующего обслуживания.

Экспериментальная поддержка ES6 классов и модулей

В этом релизе представлена экспериментальная поддержка ES6 модулей и генерации ES6 классов:

  • Модули предлагают способ упростить вашу кодовую базу и улучшить ее поддержку.

  • Классы позволяют включить принципы объектно-ориентированного программирования (ООП), что приводит к более чистому и интуитивному коду.

Для активации этих функций необходимо соответствующим образом обновить файл build.gradle.kts.

// build.gradle.kts
kotlin { 
    js(IR) { 
        useEsModules() // Enables ES6 modules
        browser()
        }
    }

// Enables ES6 classes generation
tasks.withType<KotlinJsCompile>().configureEach {
    kotlinOptions {
        useEsClasses = true
    }
}

Узнайте больше о ECMAScript 2015 (ES6) в официальной документации.

Изменение целевого каталога для JS-распределения (производство)

До Kotlin 1.9.0, целевой каталог распределения был build/distributions. Однако это общий каталог для архивов Gradle. Для решения этой проблемы, мы изменили целевой каталог распределения по умолчанию в Kotlin 1.9.0 на: build/dist/<targetName>/<binaryName>.

Например, productionExecutable находился в build/distributions. В Kotlin 1.9.0 он находится в build/dist/js/productionExecutable.

Если у вас настроена конвейерная система, использующая результаты этих сборок, убедитесь, что вы обновили каталог.

Извлечение объявлений org.w3c из stdlib-js

Начиная с Kotlin 1.9.0, stdlib-js больше не включает org.w3c объявления. Вместо этого эти объявления были перенесены в отдельную зависимость Gradle. Когда вы добавляете плагин Kotlin Multiplatform Gradle в свой файл build.gradle.kts, эти объявления будут автоматически включены в ваш проект, аналогично стандартной библиотеке.

Для этого не требуется никаких ручных действий или миграции. Необходимые корректировки будут выполнены автоматически.

Gradle

Kotlin 1.9.0 поставляется с новыми параметрами компилятора Gradle и многим другим:

  • Удаленный параметр classpath

  • Новые параметры компилятора Gradle

  • Параметры компилятора на уровне проекта для Kotlin/JVM

  • Параметр компилятора для имени модуля Kotlin/Native

  • Отдельные плагины компилятора для официальных библиотек Kotlin

  • Увеличена минимально поддерживаемая версия

  • kapt не вызывает создание задач в Gradle

  • Программная настройка режима проверки соответствия JVM-цели

Удаленный параметр classpath

В Kotlin 1.7.0 мы объявили начало цикла устаревания для свойства задачи KotlinCompile: classpath. Уровень устаревания был повышен до ERROR в Kotlin 1.8.0. В этом релизе мы окончательно удалили свойство classpath. Все задачи компиляции теперь должны использовать вход libraries для списка библиотек, необходимых для компиляции.

Новые параметры компилятора

Плагин Kotlin Gradle теперь предоставляет новые свойства для включения и прогрессивного режима компилятора.

  • Для включения новых API вы теперь можете использовать свойство optIn и передавать список строк, например: optIn.set(listOf(a, b, c)).

  • Для включения прогрессивного режима используйте progressiveMode.set(true).

Параметры компилятора на уровне проекта для Kotlin/JVM

Начиная с Kotlin 1.9.0, доступен новый блок compilerOptions внутри блока конфигурации kotlin.

kotlin {
    compilerOptions {
        jvmTarget.set(JVM.Target_11)
    }
}

Это значительно упрощает настройку параметров компилятора. Однако важно обратить внимание на некоторые детали:

  • Эта конфигурация работает только на уровне проекта.

  • Для плагина Android этот блок настраивает тот же объект, что и:

android {
    kotlinOptions {}
}
  • Блоки конфигурации android.kotlinOptions и kotlin.compilerOptions перекрывают друг друга. Последний (нижний) блок в файле сборки всегда вступает в силу.

  • Если moduleName сконфигурирован на уровне проекта, его значение может быть изменено при передаче в компилятор. Это не относится к компиляции main, но для других типов, например, тестовых источников, плагин Kotlin Gradle добавит суффикс _test.

  • Конфигурация внутри tasks.withType<KotlinJvmCompile>().configureEach {} (или tasks.named<KotlinJvmCompile>("compileKotlin") { }) перекрывает как kotlin.compilerOptions, так и android.kotlinOptions.

Параметр компилятора для имени модуля Kotlin/Native

Параметр компилятора Kotlin/Native module-name теперь легко доступен в плагине Kotlin Gradle.

Этот параметр задаёт имя модуля компиляции и также может использоваться для добавления префикса имени для объявлений, экспортируемых в Objective-C.

Теперь вы можете задать имя модуля непосредственно в блоке compilerOptions файлов сборки Gradle:

tasks.named<org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile>("compileKotlinLinuxX64") {
    compilerOptions {
        moduleName.set("my-module-name")
    }
}
tasks.named("compileKotlinLinuxX64", org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile.class) {
    compilerOptions {
        moduleName = "my-module-name"
    }
}

Отдельные плагины компилятора для официальных библиотек Kotlin

Kotlin 1.9.0 вводит отдельные плагины компилятора для своих официальных библиотек. Ранее плагины компилятора были встроены в соответствующие плагины Gradle. Это могло привести к проблемам совместимости, если плагин компилятора был скомпилирован с Kotlin-версией выше, чем версия Kotlin runtime в Gradle сборке.

Теперь плагины компилятора добавляются как отдельные зависимости, поэтому у вас больше не будет проблем совместимости со старыми версиями Gradle. Другое важное преимущество нового подхода заключается в том, что новые плагины компилятора могут использоваться с другими системами сборки, такими как Bazel.

Вот список новых плагинов компилятора, которые мы теперь публикуем в Maven Central:

  • kotlin-atomicfu-compiler-plugin

  • kotlin-allopen-compiler-plugin

  • kotlin-lombok-compiler-plugin

  • kotlin-noarg-compiler-plugin

  • kotlin-sam-with-receiver-compiler-plugin

  • kotlinx-serialization-compiler-plugin

Каждый плагин имеет свой аналог -embeddable, например, kotlin-allopen-compiler-plugin-embeddable предназначен для работы с артефактом kotlin-compiler-embeddable, — параметром по умолчанию для артефактов скриптов.

Gradle добавляет эти плагины в качестве аргументов компилятора. Вам не нужно вносить какие-либо изменения в существующие проекты.

Увеличена минимально поддерживаемая версия

Начиная с Kotlin 1.9.0, минимально поддерживаемая версия Android Gradle Plugin составляет 4.2.2.

См. совместимость плагина Kotlin Gradle с доступными версиями Gradle в нашей документации.

kapt не вызывает создание задач в Gradle

До версии 1.9.0 плагин компилятора kapt вызывал создание задач в принудительном режиме, запрашивая настроенный экземпляр задачи компиляции Kotlin. Это поведение исправлено в Kotlin 1.9.0. Если вы используете стандартную конфигурацию для файла build.gradle.kts, то ваша настройка не затронута этим изменением.

Если вы используете пользовательскую конфигурацию, ваша настройка будет затронута. Например, если вы изменили задачу KotlinJvmCompile с помощью API задач Gradle, вам необходимо аналогичным образом изменить задачу KaptGenerateStubs в файле сборки.

Например, если ваш скрипт имеет следующую конфигурацию для задачи KotlinJvmCompile:

tasks.named<KotlinJvmCompile>("compileKotlin") { // Your custom configuration }

В этом случае вам необходимо убедиться, что такое же изменение включено в задачу KaptGenerateStubs:

tasks.named<KaptGenerateStubs>("kaptGenerateStubs") { // Your custom configuration }

Дополнительную информацию можно найти в нашей записи в YouTrack.

Программная настройка режима проверки соответствия JVM-цели

До Kotlin 1.9.0 существовал только один способ настройки обнаружения несовместимости между Kotlin и Java в отношении JVM-цели. Вам нужно было установить kotlin.jvm.target.validation.mode=ERROR в gradle.properties для всего проекта.

Теперь вы также можете настроить его на уровне задачи в файле build.gradle.kts:

tasks.named<org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile>("compileKotlin") {
    jvmTargetValidationMode.set(org.jetbrains.kotlin.gradle.dsl.jvm.JvmTargetValidationMode.WARNING)
}

Стандартная библиотека

В Kotlin 1.9.0 есть несколько замечательных улучшений для стандартной библиотеки:

  • Оператор ..< и API времени API времени являются стабильными.

  • Стандартная библиотека Kotlin/Native была тщательно пересмотрена и обновлена

  • Аннотация @Volatile может использоваться на большем количестве платформ

  • Есть общая функция для получения группы захвата регулярного выражения по имени

  • Класс HexFormat был добавлен для форматирования и разбора шестнадцатеричных чисел

Стабильный оператор ..< для открытых диапазонов

Новый оператор ..< для открытых диапазонов, который был представлен в Kotlin 1.7.20 и стал стабильным в 1.8.0. В 1.9.0, API стандартной библиотеки для работы с открытыми диапазонами также является стабильным.

Наши исследования показывают, что новый оператор ..< делает легче понять, когда объявлен открытый диапазон. Если вы используете инфиксную функцию until, легко ошибиться, предположив, что верхняя граница включена.

Вот пример использования функции until:

fun main() {
    for (number in 2 until 10) {
        if (number % 2 == 0) {
            print("$number ")
        }
    }
    // 2 4 6 8
}

И вот пример использования нового оператора ..<:

fun main() {
    for (number in 2..<10) {
        if (number % 2 == 0) {
            print("$number ")
        }
    }
    // 2 4 6 8
}

С версии IntelliJ IDEA 2023.1.1 доступна новая проверка кода, которая выделяет случаи, где можно использовать оператор ..<.

Дополнительную информацию о том, что вы можете сделать с этим оператором, см. в Что нового в Kotlin 1.7.20.

Стабильный API времени

С 1.3.50 мы предварительно представили новый API измерения времени. Часть API, связанная с продолжительностью, стала стабильной в 1.6.0. В 1.9.0 остальной API измерения времени стал стабильным.

Старый API времени предоставлял функции measureTimeMillis и measureNanoTime, которые не являются интуитивно понятными в использовании. Хотя понятно, что они оба измеряют время в различных единицах, непонятно, что measureTimeMillis использует время стенных часов для измерения времени, а measureNanoTime использует монотонный источник времени. Новый API времени решает эту и другие проблемы, чтобы сделать API более удобным в использовании.

С новым API времени вы можете легко:

  • Измерить время выполнения некоторого кода, используя монотонный источник времени с желаемыми единицами времени.

  • Отметить момент времени.

  • Сравнить и найти разницу между двумя моментами времени.

  • Проверить, сколько времени прошло с определенного момента.

  • Проверить, наступил ли текущий момент времени после определенного момента.

Измерение времени выполнения кода

Чтобы измерить время выполнения блока кода, используйте инлайн-функцию measureTime.

Чтобы измерить время выполнения блока кода и вернуть результат блока кода, используйте инлайн-функцию measureTimedValue.

По умолчанию обе функции используют монотонный источник времени. Однако вы можете использовать источник времени реального хода. Например, на Android по умолчанию источник времени System.nanoTime() считает время только пока устройство активно. Он теряет отсчёт времени, когда устройство переходит в глубокий сон. Чтобы отслеживать время, когда устройство находится в глубоком сне, вы можете создать источник времени, который использует SystemClock.elapsedRealtimeNanos() вместо него:

object RealtimeMonotonicTimeSource : AbstractLongTimeSource(DurationUnit.NANOSECONDS) {
    override fun read(): Long = SystemClock.elapsedRealtimeNanos()
}

Отметка и измерение разницы во времени

Чтобы отметить определённый момент времени, используйте интерфейс TimeSource и функцию markNow() для создания TimeMark. Для измерения разницы между TimeMarks из одного источника времени используйте оператор вычитания (-):

import kotlin.time.*

fun main() {
    val timeSource = TimeSource.Monotonic
    val mark1 = timeSource.markNow()
    Thread.sleep(500) // Sleep 0.5 seconds.
    val mark2 = timeSource.markNow()

    repeat(4) { n ->
        val mark3 = timeSource.markNow()
        val elapsed1 = mark3 - mark1
        val elapsed2 = mark3 - mark2

        println("Measurement 1.${n + 1}: elapsed1=$elapsed1, elapsed2=$elapsed2, diff=${elapsed1 - elapsed2}")
    }
    // It's also possible to compare time marks with each other.
    println(mark2 > mark1) // This is true, as mark2 was captured later than mark1.
}

Чтобы проверить, пройден ли срок или истекло ли время ожидания, используйте расширяющие функции hasPassedNow() и hasNotPassedNow():

import kotlin.time.*
import kotlin.time.Duration.Companion.seconds

fun main() {
    val timeSource = TimeSource.Monotonic
    val mark1 = timeSource.markNow()
    val fiveSeconds: Duration = 5.seconds
    val mark2 = mark1 + fiveSeconds

    // It hasn't been 5 seconds yet
    println(mark2.hasPassedNow())
    // false

    // Wait six seconds
    Thread.sleep(6000)
    println(mark2.hasPassedNow())
    // true
}

Путь стандартной библиотеки Kotlin/Native к стабилизации

По мере роста нашей стандартной библиотеки для Kotlin/Native, мы решили провести её полную проверку, чтобы убедиться в соответствии высоким стандартам. В рамках этого мы тщательно рассмотрели каждый существующий публичный идентификатор. Для каждого идентификатора мы рассмотрели, соответствует ли он следующим критериям:

  • Имеет уникальное назначение.

  • Согласуется с другими API Kotlin.

  • Имеет поведение, аналогичное своему аналогу для JVM.

  • Является устойчивым к будущим изменениям.

На основе этих соображений мы приняли одно из следующих решений:

  • Сделали его Стабильным.

  • Сделали его Экспериментальным.

  • Отмечены как private.

  • Изменили его поведение.

  • Перенесли его в другое место.

  • Устарели его.

  • Отмечены как устаревшие.

Если существующий идентификатор:

  • Перенесён в другой пакет, то идентификатор всё ещё существует в исходном пакете, но теперь он устарел с уровнем устаревания: WARNING. IntelliJ IDEA автоматически предложит замены при инспекции кода.

  • Устарел, то он устарел с уровнем устаревания: WARNING.

  • Отмечен как устаревший, то вы можете продолжать его использовать, но он будет заменён в будущем.

Мы не будем перечислять все результаты обзора здесь, но вот некоторые ключевые моменты:

  • Мы стабилизировали API атомарных операций.

  • Мы сделали kotlinx.cinterop Экспериментальным, и теперь для использования пакета требуются различные опции включения. Более подробную информацию см. в разделе Явные гарантии стабильности C-совместимости.

  • Мы отметили класс Worker и его связанные API как устаревшие.

  • Мы отметили класс BitSet как устаревший.

  • Мы отметили все public API в пакете kotlin.native.internal как private или перенесли их в другие пакеты.

Явные гарантии стабильности C-совместимости

Для поддержания высокого качества нашего API мы решили сделать kotlinx.cinterop Экспериментальным. Несмотря на то, что kotlinx.cinterop было тщательно протестировано, для достижения уровня стабильности ещё есть возможность улучшения. Мы рекомендуем использовать этот API для межплатформенной совместимости, но ограничить его применение конкретными областями в ваших проектах. Это упростит миграцию, когда мы начнём развивать этот API, чтобы сделать его стабильным.

Если вы хотите использовать C-подобные внешние API, такие как указатели, вы должны включить @OptIn(ExperimentalForeignApi), иначе ваш код не будет компилироваться.

Для использования остальной части kotlinx.cinterop, которая охватывает межплатформенную совместимость Objective-C/Swift, вы должны включить @OptIn(BetaInteropApi).

Дополнительную информацию об этих аннотациях можно найти в нашем исходном коде для Annotations.kt.

Дополнительную информацию обо всех изменениях в рамках этого обзора можно найти на нашей странице YouTrack.

Мы будем рады любым вашим отзывам! Вы можете оставить свои комментарии непосредственно на странице.

Стабильная аннотация @Volatile

Если вы аннотируете свойство var аннотацией @Volatile, то соответствующее поле отмечается как атомарное, и любые чтение или запись в это поле будут атомарными, а записи всегда будут видны другим потокам.

До версии 1.8.20 аннотация kotlin.jvm.Volatile была доступна в общей стандартной библиотеке. Однако эта аннотация была эффективной только на JVM. Если вы использовали её на других платформах, она игнорировалась, что приводило к ошибкам.

В версии 1.8.20 мы представили экспериментальную общую аннотацию kotlin.concurrent.Volatile, которую можно было предварительно просмотреть как на JVM, так и на Kotlin/Native.

В версии 1.9.0 аннотация kotlin.concurrent.Volatile стала стабильной. Если вы используете аннотацию kotlin.jvm.Volatile в своих многоплатформенных проектах, мы рекомендуем перейти на аннотацию kotlin.concurrent.Volatile.

Новая общая функция для получения группы совпадений регулярного выражения по имени

До версии 1.9.0 каждая платформа имела собственное расширение для получения группы совпадений регулярного выражения по имени из результата сопоставления. Однако общей функции не существовало. До Kotlin 1.8.0 общая функция была невозможна, так как стандартная библиотека всё ещё поддерживала JVM-цели 1.6 и 1.7.

Начиная с Kotlin 1.8.0, стандартная библиотека компилируется с JVM-целью 1.8. Поэтому в версии 1.9.0 появилась общая функция groups, которую можно использовать для извлечения содержимого группы по её имени для результата сопоставления регулярного выражения. Это полезно при необходимости доступа к результатам сопоставления регулярного выражения, относящимся к конкретной группе совпадений.

Вот пример с регулярным выражением, содержащим три группы совпадений: city, state и areaCode. Вы можете использовать эти имена групп для доступа к сопоставленным значениям:

fun main() {
    val regex = """\b(?<city>[A-Za-z\s]+),\s(?<state>[A-Z]{2}):\s(?<areaCode>[0-9]{3})\b""".toRegex()
    val input = "Coordinates: Austin, TX: 123"
    
    val match = regex.find(input)!!
    println(match.groups["city"]?.value)
    // Austin
    println(match.groups["state"]?.value)
    // TX
    println(match.groups["areaCode"]?.value)
    // 123
}

Новая утилита для создания родительских каталогов

В версии 1.9.0 появилась новая функция-расширение createParentDirectories(), которую можно использовать для создания нового файла со всеми необходимыми родительскими каталогами. При передаче пути к файлу функции createParentDirectories() проверяется, существуют ли родительские каталоги. Если они существуют, ничего не делается. Если нет, они создаются.

createParentDirectories() особенно полезна при копировании файлов. Например, её можно использовать в сочетании с функцией copyToRecursively().

sourcePath.copyToRecursively(
   destinationPath.createParentDirectories(), 
   followLinks = false
)

Новый класс HexFormat для форматирования и разбора шестнадцатеричных чисел

Новый класс HexFormat и связанные с ним расширяющие функции являются Экспериментальными, и для их использования вы можете включить их с помощью @OptIn(ExperimentalStdlibApi::class) или аргумента компилятора -opt-in=kotlin.ExperimentalStdlibApi.

В версии 1.9.0 класс HexFormat и связанные с ним расширяющие функции предоставляются как экспериментальная возможность, которая позволяет конвертировать числовые значения в шестнадцатеричные строки и обратно. В частности, вы можете использовать расширяющие функции для преобразования между шестнадцатеричными строками и ByteArrays или другими числовыми типами (Int, Short, Long).

Например:

println(93.toHexString()) // "0000005d"

Класс HexFormat включает параметры форматирования, которые можно настроить с помощью билдера HexFormat{}.

Если вы работаете с ByteArrays, у вас есть следующие опции, настраиваемые свойствами:

Опция

Описание

upperCase

Используются ли прописные или строчные шестнадцатеричные цифры. По умолчанию используются строчные. upperCase = false.

bytes.bytesPerLine

Максимальное количество байтов на строку.

bytes.bytesPerGroup

Максимальное количество байтов в группе.

bytes.bytesSeparator

Разделитель между байтами. По умолчанию ничего.

bytes.bytesPrefix

Строка, предшествующая двузначному шестнадцатеричному представлению каждого байта. По умолчанию ничего.

bytes.bytesSuffix

Строка, следующая за двузначным шестнадцатеричным представлением каждого байта. По умолчанию ничего.

Например:

val macAddress = "001b638445e6".hexToByteArray()

// Use HexFormat{} builder to separate the hexadecimal string by colons
println(macAddress.toHexString(HexFormat { bytes.byteSeparator = ":" }))
// "00:1b:63:84:45:e6"

// Use HexFormat{} builder to:
// * Make the hexadecimal string uppercase
// * Group the bytes in pairs
// * Separate by periods
val threeGroupFormat = HexFormat { upperCase = true; bytes.bytesPerGroup = 2; bytes.groupSeparator = "." }

println(macAddress.toHexString(threeGroupFormat))
// "001B.6384.45E6"

Если вы работаете с числовыми типами, у вас есть следующие опции, настраиваемые свойствами:

Опция

Описание

number.prefix

Префикс шестнадцатеричной строки. По умолчанию ничего.

number.suffix

Суффикс шестнадцатеричной строки. По умолчанию ничего.

number.removeLeadingZeros

Убирать ли ведущие нули в шестнадцатеричной строке. По умолчанию ведущие нули не удаляются. number.removeLeadingZeros = false

Например:

// Use HexFormat{} builder to parse a hexadecimal that has prefix: "0x".
println("0x3a".hexToInt(HexFormat { number.prefix = "0x" })) // "58"

Обновления документации

Документация Kotlin претерпела заметные изменения:

  • Обзор Kotlin – изучите основы языка Kotlin с разделами, содержащими как теоретические, так и практические примеры.

  • Структура Android-модулей – узнайте о новой структуре Android-модулей.

  • Руководство по совместимости для Kotlin Multiplatform – узнайте о несовместимых изменениях, с которыми вы можете столкнуться при разработке проектов с Kotlin Multiplatform.

  • Kotlin/Wasm – узнайте о Kotlin/Wasm и о том, как использовать его в своих проектах Kotlin Multiplatform.

  • Добавление зависимостей от библиотек Kotlin в проекты Kotlin/Wasm – узнайте о поддерживаемых библиотеках Kotlin для Kotlin/Wasm.

Установка Kotlin 1.9.0

Проверка версии IDE

IntelliJ IDEA 2022.3.3 и 2023.1.1 автоматически предлагают обновить плагин Kotlin до версии 1.9.0. IntelliJ IDEA 2023.2 будет включать плагин Kotlin 1.9.0.

Android Studio Giraffe (223) и Hedgehog (231) будут поддерживать Kotlin 1.9.0 в своих будущих выпусках.

Новый компилятор командной строки доступен для скачивания на странице выпусков GitHub.

Настройка настроек Gradle

Для загрузки артефактов и зависимостей Kotlin обновите свой файл settings.gradle(.kts) для использования репозитория Maven Central:

pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
}

Если репозиторий не указан, Gradle использует устаревший репозиторий JCenter, что может привести к проблемам с артефактами Kotlin.

Руководство по совместимости для Kotlin 1.9.0

Kotlin 1.9.0 является релизом с новыми функциями и, следовательно, может вносить изменения, несовместимые с вашим кодом, написанным для более ранних версий языка. Подробный список этих изменений можно найти в руководстве по совместимости для Kotlin 1.9.0.

Последнее изменение: 12 июля 2023
Kotlin для соревновательного программирования Что нового в Kotlin 1.8.20

© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew19.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API