Что нового в Kotlin 1.5.30
Дата выхода: 24 августа 2021 года
Kotlin 1.5.30 предлагает обновления языка, включая предварительные версии будущих изменений, различные улучшения поддержки платформ и инструментов, а также новые функции стандартной библиотеки.
Вот некоторые основные улучшения:
Функции языка, включая экспериментальные утверждения sealed
when, изменения в использовании требования opt-in и другиеПоддержка Apple silicon
Бета-версия бэкенда Kotlin/JS IR
Улучшенная работа плагина Gradle
Вы также можете найти краткий обзор изменений в записи блога о выпуске и этом видео:
Особенности языка
Kotlin 1.5.30 предоставляет предварительные версии будущих изменений языка и вносит улучшения в механизм требования opt-in и вывод типов:
Требование opt-in при неявном использовании экспериментальных API
Изменения в использовании аннотаций требования opt-in с различными целевыми объектами
Исчерпывающие операторы when для sealed и Boolean
Оператор исчерпывающий when содержит ветви для всех возможных типов или значений его объекта или для некоторых типов плюс else ветвь. Другими словами, он охватывает все возможные случаи.
Мы планируем вскоре запретить неполные when операторы, чтобы обеспечить согласованность с when выражениями. Для плавной миграции вы можете настроить компилятор на выдачу предупреждений о неполных when операторах с sealed классом или Boolean. Такие предупреждения будут появляться по умолчанию в Kotlin 1.6 и в дальнейшем будут считаться ошибками.
sealed class Mode {
object ON : Mode()
object OFF : Mode()
}
fun main() {
val x: Mode = Mode.ON
when (x) {
Mode.ON -> println("ON")
}
// WARNING: Non exhaustive 'when' statements on sealed classes/interfaces
// will be prohibited in 1.7, add an 'OFF' or 'else' branch instead
val y: Boolean = true
when (y) {
true -> println("true")
}
// WARNING: Non exhaustive 'when' statements on Booleans will be prohibited
// in 1.7, add a 'false' or 'else' branch instead
}
Чтобы включить эту функцию в Kotlin 1.5.30, используйте версию языка 1.6. Вы также можете изменить предупреждения на ошибки, включив постепенный режим.
kotlin {
sourceSets.all {
languageSettings.apply {
languageVersion = "1.6"
//progressiveMode = true // false by default
}
}
}
kotlin {
sourceSets.all {
languageSettings {
languageVersion = '1.6'
//progressiveMode = true // false by default
}
}
}
Функции-подвески в качестве супертипов
Kotlin 1.5.30 предоставляет предварительный просмотр возможности использования функционального типа suspend в качестве супертипа с некоторыми ограничениями.
class MyClass: suspend () -> Unit {
override suspend fun invoke() { TODO() }
}
Используйте опцию компилятора -language-version 1.6, чтобы включить эту функцию:
kotlin {
sourceSets.all {
languageSettings.apply {
languageVersion = "1.6"
}
}
}
kotlin {
sourceSets.all {
languageSettings {
languageVersion = '1.6'
}
}
}
Функция имеет следующие ограничения:
Вы не можете смешивать обычный функциональный тип и функциональный тип
suspendв качестве супертипа. Это связано с особенностями реализацииsuspendфункциональных типов в JVM-бэкенде. Они представлены в нем как обычные функциональные типы с маркерным интерфейсом. Из-за маркерного интерфейса нельзя определить, какие суперинтерфейсы являются подвешенными, а какие — обычными.Вы не можете использовать несколько
suspendфункциональных супертипов. Если есть проверки типов, вы также не можете использовать несколько обычных функциональных супертипов.
Требование opt-in при неявном использовании экспериментальных API
Автор библиотеки может отметить экспериментальный API как требующий opt-in, чтобы проинформировать пользователей об его экспериментальном статусе. Компилятор выдает предупреждение или ошибку при использовании API, требующего явного согласия для его подавления.
В Kotlin 1.5.30 компилятор рассматривает любое объявление, имеющее экспериментальный тип в сигнатуре, как экспериментальное. Иными словами, он требует opt-in даже для неявного использования экспериментального API. Например, если тип возвращаемого значения функции помечен как экспериментальный элемент API, использование этой функции требует opt-in, даже если само объявление не помечено как требующее opt-in явно.
// Library code
@RequiresOptIn(message = "This API is experimental.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
annotation class MyDateTime // Opt-in requirement annotation
@MyDateTime
class DateProvider // A class requiring opt-in
// Client code
// Warning: experimental API usage
fun createDateSource(): DateProvider { /* ... */ }
fun getDate(): Date {
val dateSource = createDateSource() // Also warning: experimental API usage
// ...
}
Узнайте больше о требованиях opt-in.
Изменения в использовании аннотаций требования opt-in с различными целевыми объектами
Kotlin 1.5.30 представляет новые правила для использования и объявления аннотаций требования opt-in на различных целевых объектах. Компилятор теперь сообщает об ошибке для случаев, которые трудно обрабатывать во время компиляции. В Kotlin 1.5.30:
Размещение аннотаций требования opt-in на локальных переменных и параметрах значений запрещено в месте использования.
Размещение аннотации на ключевом слове override разрешено только в том случае, если базовое объявление также помечено.
Размещение аннотаций на вспомогательных полях и геттерах запрещено. Можно пометить основное свойство вместо этого.
Установка
TYPEиTYPE_PARAMETERцелевых аннотаций запрещена на месте объявления аннотации требования opt-in.
Узнайте больше о требованиях opt-in.
Улучшения вывода типов для рекурсивных обобщенных типов
В Kotlin и Java можно определить рекурсивный обобщенный тип, который ссылается на себя в параметрах типа. В Kotlin 1.5.30 компилятор Kotlin может вывести аргумент типа, основываясь только на верхних границах соответствующего параметра типа, если это рекурсивный обобщенный тип. Это позволяет создавать различные шаблоны с рекурсивными обобщенными типами, которые часто используются в Java для создания API билдеров.
// Kotlin 1.5.20
val containerA = PostgreSQLContainer<Nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
withDatabaseName("db")
withUsername("user")
withPassword("password")
withInitScript("sql/schema.sql")
}
// Kotlin 1.5.30
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
.withDatabaseName("db")
.withUsername("user")
.withPassword("password")
.withInitScript("sql/schema.sql")
Вы можете включить улучшения, передав опции компилятора -Xself-upper-bound-inference или -language-version 1.6. См. другие примеры новых поддерживаемых вариантов использования в этом тикете YouTrack.
Устранение ограничений вывода типов билдера
Вывод типов билдера — это особый вид вывода типов, который позволяет выводить аргументы типа вызова на основе информации о типе из других вызовов внутри лямбда-аргумента. Это может быть полезно при вызове универсальных функций билдера, таких как buildList() или sequence(): buildList { add("string") }.
Внутри такого лямбда-аргумента ранее существовало ограничение на использование информации о типе, которую пытался вывести вывод типов билдера. Это означает, что вы можете только указать тип, но не получить его. Например, вы не можете вызвать get() внутри лямбда-аргумента buildList() без явного указания аргументов типа.
Kotlin 1.5.30 устраняет эти ограничения с помощью опции компилятора -Xunrestricted-builder-inference. Добавьте эту опцию, чтобы включить ранее запрещённые вызовы внутри лямбда-аргумента универсальных функций билдера:
@kotlin.ExperimentalStdlibApi
val list = buildList {
add("a")
add("b")
set(1, null)
val x = get(1)
if (x != null) {
removeAt(1)
}
}
@kotlin.ExperimentalStdlibApi
val map = buildMap {
put("a", 1)
put("b", 1.1)
put("c", 2f)
}
Также вы можете включить эту функцию с помощью опции компилятора -language-version 1.6.
Kotlin/JVM
В Kotlin 1.5.30 Kotlin/JVM получило следующие функции:
См. раздел Gradle для обновлений плагина Kotlin Gradle для платформы JVM.
Создание экземпляров аннотационных классов
В Kotlin 1.5.30 теперь можно вызывать конструкторы классов-аннотаций в произвольном коде для получения экземпляра. Эта функция охватывает те же сценарии, что и соглашение Java, позволяющее реализовывать интерфейс аннотации.
annotation class InfoMarker(val info: String)
fun processInfo(marker: InfoMarker) = ...
fun main(args: Array<String>) {
if (args.size != 0)
processInfo(getAnnotationReflective(args))
else
processInfo(InfoMarker("default"))
}
Используйте опцию компилятора -language-version 1.6, чтобы включить эту функцию. Обратите внимание, что все текущие ограничения для классов аннотаций, такие как ограничения на определение параметров, отличных от вторичных конструкторов, или членов, не являющихся val, остаются неизменными.
Дополнительную информацию о создании экземпляров аннотационных классов можно найти в этом KEEP
Улучшенная конфигурация поддержки аннотаций нулевости
Компилятор Kotlin может читать различные типы аннотаций нулевости, чтобы получить информацию о нулевости из Java. Эта информация позволяет ему сообщать о несоответствиях нулевости в Kotlin при вызове кода Java.
В Kotlin 1.5.30 вы можете указать, следует ли компилятору сообщать о несоответствиях нулевости на основе информации из определённых типов аннотаций нулевости. Просто используйте опцию компилятора -Xnullability-annotations=@<package-name>:<report-level>. В аргументе укажите полное имя пакета аннотаций нулевости и один из этих уровней отчёта:
ignore, чтобы игнорировать несоответствия нулевостиwarn, чтобы сообщать предупрежденияstrict, чтобы сообщать об ошибках.
См. полный список поддерживаемых аннотаций нулевости вместе с их полными именами пакетов.
Вот пример, демонстрирующий, как включить отчёт об ошибках для недавно поддерживаемых аннотаций нулевости RxJava 3: -Xnullability-annotations=@io.reactivex.rxjava3.annotations:strict. Обратите внимание, что по умолчанию все такие несоответствия нулевости являются предупреждениями.
Kotlin/Native
В Kotlin/Native были внесены различные изменения и улучшения:
Улучшенное отображение Swift/Objective-C для объектов и компаньонов
Устаревание связи с DLL без библиотек импорта для целей MinGW
Поддержка Apple Silicon
Kotlin 1.5.30 вводит поддержку Apple Silicon.
Ранее для работы с хостами Apple Silicon компилятор и инструменты Kotlin/Native требовали среды перевода Rosetta. В Kotlin 1.5.30 среда перевода больше не нужна — компилятор и инструменты могут работать на оборудовании Apple Silicon без дополнительных действий.
Мы также добавили новые целевые платформы, которые позволяют Kotlin-коду работать напрямую на Apple Silicon:
macosArm64iosSimulatorArm64watchosSimulatorArm64tvosSimulatorArm64
Они доступны как на системах на базе Intel, так и на системах с Apple Silicon. Все существующие целевые платформы также доступны на хостах Apple Silicon.
Обратите внимание, что в 1.5.30 мы предоставляем только базовые средства поддержки целевых платформ Apple Silicon в плагине Gradle kotlin-multiplatform. В частности, новые целевые симуляторы не включены в ios, tvos и watchos сокращения целевых платформ. Узнайте, как использовать целевые платформы Apple Silicon с сокращениями целевых платформ. Мы будем продолжать работу над улучшением пользовательского опыта с новыми целевыми платформами.
Улучшенное Kotlin DSL для плагина CocoaPods Gradle
Новые параметры для фреймворков Kotlin/Native
Kotlin 1.5.30 вводит улучшенное DSL для плагина CocoaPods Gradle для фреймворков Kotlin/Native. Помимо имени фреймворка, вы можете указать другие параметры в конфигурации под:
Укажите динамическую или статическую версию фреймворка
Включить явное экспорт зависимостей
Включить встраивание Bitcode
Чтобы использовать новое DSL, обновите свой проект до Kotlin 1.5.30 и укажите параметры в разделе cocoapods вашего файла build.gradle(.kts):
cocoapods {
frameworkName = "MyFramework" // This property is deprecated
// and will be removed in future versions
// New DSL for framework configuration:
framework {
// All Framework properties are supported
// Framework name configuration. Use this property instead of
// deprecated 'frameworkName'
baseName = "MyFramework"
// Dynamic framework support
isStatic = false
// Dependency export
export(project(":anotherKMMModule"))
transitiveExport = false // This is default.
// Bitcode embedding
embedBitcode(BITCODE)
}
}
Поддержка пользовательских имен для конфигурации Xcode
Плагин Kotlin CocoaPods Gradle поддерживает пользовательские имена в конфигурации сборки Xcode. Это также пригодится, если вы используете специальные имена для конфигурации сборки в Xcode, например Staging.
Чтобы указать пользовательское имя, используйте параметр xcodeConfigurationToNativeBuildType в разделе cocoapods вашего файла build.gradle(.kts):
cocoapods {
// Maps custom Xcode configuration to NativeBuildType
xcodeConfigurationToNativeBuildType["CUSTOM_DEBUG"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["CUSTOM_RELEASE"] = NativeBuildType.RELEASE
}
Этот параметр не отобразится в файле Podspec. При выполнении процесса сборки Gradle Xcode плагин Kotlin CocoaPods Gradle выберет необходимый тип сборки нативных библиотек.
Экспериментальная совместимость с Swift 5.5 async/await
Мы добавили поддержку вызова Kotlin-подвешенных функций из Objective-C и Swift в 1.4.0, и теперь мы улучшаем ее, чтобы соответствовать новой функции Swift 5.5 — асинхронность с async и await модификаторами.
Компилятор Kotlin/Native теперь генерирует атрибут _Nullable_result в сгенерированных заголовках Objective-C для подвешенных функций с типом возвращаемого значения nullable. Это позволяет вызывать их из Swift как async функции с правильной маркировкой nullable.
Обратите внимание, что эта функция экспериментальная и может быть изменена в будущем как в Kotlin, так и в Swift. Пока мы предоставляем предварительный просмотр этой функции с определенными ограничениями, и с нетерпением ждем вашего отзыва. Узнайте больше о ее текущем состоянии и оставьте свой отзыв на этом вопросе в YouTrack.
Улучшенное отображение Swift/Objective-C для объектов и компаньонов
Теперь доступ к объектам и компаньонам может быть реализован более интуитивно для разработчиков нативных iOS. Например, если у вас есть следующие объекты в Kotlin:
object MyObject {
val x = "Some value"
}
class MyClass {
companion object {
val x = "Some value"
}
}
Чтобы получить к ним доступ в Swift, вы можете использовать свойства shared и companion:
MyObject.shared MyObject.shared.x MyClass.companion MyClass.Companion.shared
Узнайте больше о совместимости Swift/Objective-C.
Устаревание связи с DLL без библиотек импорта для целей MinGW
LLD — это компоновщик из проекта LLVM, который мы планируем использовать в Kotlin/Native для целей MinGW из-за его преимуществ по сравнению с стандартным ld.bfd — в первую очередь, лучшей производительности.
Однако последняя стабильная версия LLD не поддерживает прямую связь с DLL для целей MinGW (Windows). Для такой связи требуется использование библиотек импорта. Хотя они не нужны с Kotlin/Native 1.5.30, мы добавляем предупреждение, чтобы проинформировать вас о том, что такое использование несовместимо с LLD, который в будущем станет стандартным компоновщиком для MinGW.
Пожалуйста, поделитесь своими мыслями и замечаниями о переходе к компоновщику LLD на этом вопросе на YouTrack.
Kotlin Многоплатформенная
1.5.30 содержит следующие заметные обновления для Kotlin Многоплатформенной:
Возможность использования пользовательских
cinteropбиблиотек в совместном коде нативных платформНовая настройка по умолчанию для публикации артефактов Android
Возможность использования пользовательских библиотек cinterop в совместном коде нативных платформ
Kotlin Многоплатформенная предоставляет возможность использования зависимых от платформы библиотек interop в общих наборах исходного кода. До версии 1.5.30 это работало только с библиотеками платформы, поставляемыми с Kotlin/Native. Начиная с 1.5.30, вы можете использовать свои пользовательские cinterop библиотеки. Для включения этой функции добавьте свойство kotlin.mpp.enableCInteropCommonization=true в свой gradle.properties:
kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.native.enableDependencyPropagation=false kotlin.mpp.enableCInteropCommonization=true
Поддержка XCFrameworks
Все проекты Kotlin Многоплатформенная теперь могут иметь XCFrameworks в качестве формата вывода. Apple представила XCFrameworks как замену универсальным (fat) фреймворкам. С помощью XCFrameworks вы:
Можете собрать логику для всех целевых платформ и архитектур в одном пакете.
Не нужно удалять все ненужные архитектуры перед публикацией приложения в App Store.
XCFrameworks полезно, если вы хотите использовать свой Kotlin фреймворк для устройств и симуляторов на Apple M1.
Для использования XCFrameworks обновите свой скрипт build.gradle(.kts):
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
plugins {
kotlin("multiplatform")
}
kotlin {
val xcf = XCFramework()
ios {
binaries.framework {
baseName = "shared"
xcf.add(this)
}
}
watchos {
binaries.framework {
baseName = "shared"
xcf.add(this)
}
}
tvos {
binaries.framework {
baseName = "shared"
xcf.add(this)
}
}
}
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFrameworkConfig
plugins {
id 'org.jetbrains.kotlin.multiplatform'
}
kotlin {
def xcf = new XCFrameworkConfig(project)
ios {
binaries.framework {
baseName = "shared"
xcf.add(it)
}
}
watchos {
binaries.framework {
baseName = "shared"
xcf.add(it)
}
}
tvos {
binaries.framework {
baseName = "shared"
xcf.add(it)
}
}
}
При объявлении XCFrameworks будут зарегистрированы эти новые задачи Gradle:
assembleXCFrameworkassembleDebugXCFramework(дополнительно артефакт отладки, содержащий dSYMs)assembleReleaseXCFramework
Узнайте больше о XCFrameworks в этом видео WWDC.
Новая настройка по умолчанию для публикации артефактов Android
Используя плагин maven-publish Gradle, вы можете опубликовать свою многоплатформенную библиотеку для целевой платформы Android, указав имена вариантов Android в скрипте сборки. Плагин Kotlin Gradle сгенерирует публикации автоматически.
До версии 1.5.30 сгенерированная метаданные публикации метаданных содержали атрибуты типа сборки для каждого опубликованного варианта Android, что делало его совместимым только с тем же типом сборки, который используется потребителем библиотеки. Kotlin 1.5.30 вводит новую настройку по умолчанию для публикации:
Если все варианты Android, которые проект публикует, имеют одинаковый атрибут типа сборки, то опубликованные варианты не будут иметь атрибут типа сборки и будут совместимы с любым типом сборки.
Если опубликованные варианты имеют разные атрибуты типа сборки, то будут опубликованы только те, которые имеют значение
release, без атрибута типа сборки. Это делает варианты релизов совместимыми с любым типом сборки на стороне потребителя, в то время как варианты не релизов будут совместимы только с соответствующими типами сборки потребителя.
Чтобы отказаться от этого и сохранить атрибуты типа сборки для всех вариантов, вы можете установить это свойство Gradle: kotlin.android.buildTypeAttribute.keep=true.
Kotlin/JS
В Kotlin/JS с версией 1.5.30 появились два основных улучшения:
Бета-версия компилятора JS IR бэкенда
Базовая часть компилятора на основе IR для Kotlin/JS, которая была представлена в 1.4.0 в Альфа версии, достигла стадии Бета.
Ранее мы опубликовали руководство по миграции для JS IR бэкенда, чтобы помочь вам мигрировать ваши проекты на новый бэкенд. Теперь мы хотим представить плагин IDE Kotlin/JS Inspection Pack, который отображает необходимые изменения прямо в IntelliJ IDEA.
Улучшенный опыт отладки для приложений с Kotlin/JS IR бэкендом
Kotlin 1.5.30 добавляет генерацию JavaScript source map для Kotlin/JS IR бэкенда. Это улучшит опыт отладки Kotlin/JS при включенном IR бэкенде, с полной поддержкой отладки, включая точки останова, пошаговое выполнение и читаемые трассы стека с надлежащими ссылками на исходный код.
Узнайте, как отлаживать Kotlin/JS в браузере или IntelliJ IDEA Ultimate.
Gradle
В рамках нашей миссии по улучшению пользовательского опыта плагина Kotlin Gradle, мы реализовали следующие функции:
Поддержка Java-инструментариев, которая включает возможность указать домашний каталог JDK с помощью интерфейса
UsesKotlinJavaToolchainдля более старых версий GradleБолее простой способ явно указать JVM-аргументы демона Kotlin
Поддержка Java-инструментариев
Gradle 6.7 ввёл функцию "Поддержка Java-инструментариев". Используя эту функцию, вы можете:
Выполнять компиляции, тесты и исполняемые файлы с использованием JDK и JRE, отличных от Gradle.
Компилировать и тестировать код с невыпущенной версией языка.
С поддержкой инструментариев Gradle может автоматически обнаруживать локальные JDK и устанавливать недостающие JDK, необходимые Gradle для сборки. Теперь сам Gradle может работать с любым JDK и по-прежнему использовать функцию кэширования сборки build cache.
Плагин Kotlin Gradle поддерживает Java-инструментарии для задач компиляции Kotlin/JVM. Java-инструментарий:
-
Устанавливает
jdkHomeпараметр, доступный для целей JVM. Устанавливает
kotlinOptions.jvmTargetна версию JDK инструментария, если пользователь не установил параметрjvmTargetявно. Если инструментарий не настроен, полеjvmTargetиспользует значение по умолчанию. Дополнительную информацию см. в соответствии JVM-целей.Влияет на то, на каких JDK
kaptрабочие процессы выполняются.
Используйте следующий код для установки инструментария. Замените заполнитель <MAJOR_JDK_VERSION> на версию JDK, которую вы хотите использовать:
kotlin {
jvmToolchain {
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
}
}
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
}
}
Обратите внимание, что установка инструментария через расширение kotlin также обновит инструментарий для задач компиляции Java.
Вы можете установить инструментарий через расширение java, и задачи компиляции Kotlin будут его использовать:
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
}
}
Дополнительную информацию о настройке любой версии JDK для задач KotlinCompile см. в документации о установке версии JDK с помощью Task DSL.
Для версий Gradle с 6.1 по 6.6 используйте интерфейс UsesKotlinJavaToolchain для установки домашнего каталога JDK.
Установка домашнего каталога JDK с помощью интерфейса UsesKotlinJavaToolchain
Все задачи Kotlin, которые поддерживают установку JDK с помощью kotlinOptions, теперь реализуют интерфейс UsesKotlinJavaToolchain. Для установки домашнего каталога JDK укажите путь к вашему JDK и замените заполнитель <JDK_VERSION>:
project.tasks
.withType<UsesKotlinJavaToolchain>()
.configureEach {
it.kotlinJavaToolchain.jdk.use(
"/path/to/local/jdk",
JavaVersion.<LOCAL_JDK_VERSION>
)
}
project.tasks
.withType(UsesKotlinJavaToolchain.class)
.configureEach {
it.kotlinJavaToolchain.jdk.use(
'/path/to/local/jdk',
JavaVersion.<LOCAL_JDK_VERSION>
)
}
Для версий Gradle с 6.1 по 6.6 используйте интерфейс UsesKotlinJavaToolchain. Начиная с Gradle 6.7, используйте Java-инструментарии.
При использовании этой функции обратите внимание, что рабочие процессы задачи kapt будут использовать только режим изоляции процессов process isolation mode, и свойство kapt.workers.isolation будет игнорироваться.
Более простой способ явно указать JVM-аргументы демона Kotlin
В Kotlin 1.5.30 была реализована новая логика для JVM-аргументов демона Kotlin. Каждый из следующих параметров переопределяет предыдущие:
-
Если ничего не указано, демон Kotlin наследует аргументы от демона Gradle (как и прежде). Например, в файле
gradle.properties:org.gradle.jvmargs=-Xmx1500m -Xms=500m
-
Если JVM-аргументы демона Gradle имеют системную переменную
kotlin.daemon.jvm.options, используйте её как прежде:org.gradle.jvmargs=-Dkotlin.daemon.jvm.options=-Xmx1500m -Xms=500m
-
Вы можете добавить системную переменную
kotlin.daemon.jvmargsв файлgradle.properties:kotlin.daemon.jvmargs=-Xmx1500m -Xms=500m
-
Вы можете указать аргументы в расширении
kotlin:kotlin { kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC") }kotlin { kotlinDaemonJvmArgs = ["-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"] } -
Вы можете указать аргументы для конкретной задачи:
tasks .matching { it.name == "compileKotlin" && it is CompileUsingKotlinDaemon } .configureEach { (this as CompileUsingKotlinDaemon).kotlinDaemonJvmArguments.set(listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")) }tasks .matching { it.name == "compileKotlin" && it instanceof CompileUsingKotlinDaemon } .configureEach { kotlinDaemonJvmArguments.set(["-Xmx1g", "-Xms512m"]) }
Дополнительную информацию о демоне Kotlin см. в документации о демоне Kotlin и его использовании с Gradle.
Стандартная библиотека
Kotlin 1.5.30 внедряет улучшения в API стандартной библиотеки Duration и Regex:
Изменение вывода Duration.toString()
До Kotlin 1.5.30 функция Duration.toString() возвращала строковое представление аргумента, выраженного в единицах, которые давали наиболее компактное и удобочитаемое числовое значение. Отныне она будет возвращать строку, выраженную как комбинацию числовых компонентов, каждый в собственных единицах. Каждый компонент — это число, за которым следует сокращённое название единицы: d, h, m, s. Например:
Пример вызова функции |
Предыдущий вывод |
Текущий вывод |
|---|---|---|
Duration.days(45).toString() |
|
|
Duration.days(1.5).toString() |
|
|
Duration.minutes(1230).toString() |
|
|
Duration.minutes(2415).toString() |
|
|
Duration.minutes(920).toString() |
|
|
Duration.seconds(1.546).toString() |
|
|
Duration.milliseconds(25.12).toString() |
|
|
Также был изменён способ представления отрицательных временных промежутков. Отрицательная продолжительность предваряется знаком минус (-), а если она состоит из нескольких компонентов, то заключена в скобки: -12m и -(1h 30m).
Обратите внимание, что короткие временные промежутки менее одной секунды отображаются как одно число с одной из единиц долей секунды. Например, ms (миллисекунды), us (микросекунды) или ns (наносекунды): 140.884ms, 500us, 24ns. Научная запись больше не используется для их представления.
Если вам нужно выразить продолжительность в одной единице, используйте перегруженную функцию Duration.toString(unit, decimals).
Парсинг Duration из строки
В Kotlin 1.5.30 в API Duration появились новые функции:
-
parse(), которая поддерживает парсинг результатов: parseIsoString(), которая парсит только из формата, созданногоtoIsoString().parseOrNull()иparseIsoStringOrNull(), которые ведут себя подобно вышеперечисленным функциям, но возвращаютnullвместо выбросаIllegalArgumentExceptionпри некорректном формате продолжительности.
Вот несколько примеров использования parse() и parseOrNull():
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
@ExperimentalTime
fun main() {
//sampleStart
val isoFormatString = "PT1H30M"
val defaultFormatString = "1h 30m"
val singleUnitFormatString = "1.5h"
val invalidFormatString = "1 hour 30 minutes"
println(Duration.parse(isoFormatString)) // "1h 30m"
println(Duration.parse(defaultFormatString)) // "1h 30m"
println(Duration.parse(singleUnitFormatString)) // "1h 30m"
//println(Duration.parse(invalidFormatString)) // throws exception
println(Duration.parseOrNull(invalidFormatString)) // "null"
//sampleEnd
}
И вот примеры использования parseIsoString() и parseIsoStringOrNull():
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
@ExperimentalTime
fun main() {
//sampleStart
val isoFormatString = "PT1H30M"
val defaultFormatString = "1h 30m"
println(Duration.parseIsoString(isoFormatString)) // "1h 30m"
//println(Duration.parseIsoString(defaultFormatString)) // throws exception
println(Duration.parseIsoStringOrNull(defaultFormatString)) // "null"
//sampleEnd
}
Сопоставление с регулярным выражением в определенной позиции
Новые функции Regex.matchAt() и Regex.matchesAt() позволяют проверить, есть ли точное соответствие регулярному выражению в определённой позиции в String или CharSequence.
matchesAt() возвращает логическое значение:
fun main(){
//sampleStart
val releaseText = "Kotlin 1.5.30 is released!"
// regular expression: one digit, dot, one digit, dot, one or more digits
val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
println(versionRegex.matchesAt(releaseText, 0)) // "false"
println(versionRegex.matchesAt(releaseText, 7)) // "true"
//sampleEnd
}
matchAt() возвращает совпадение, если оно найдено, или null, если нет:
fun main(){
//sampleStart
val releaseText = "Kotlin 1.5.30 is released!"
val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
println(versionRegex.matchAt(releaseText, 0)) // "null"
println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
//sampleEnd
}
Разбиение регулярного выражения на последовательность
Новая функция Regex.splitToSequence() является ленивым аналогом split(). Она разбивает строку вокруг совпадений с заданным регулярным выражением, но возвращает результат как последовательность, так что все операции с этим результатом выполняются лениво.
fun main(){
//sampleStart
val colorsText = "green, red , brown&blue, orange, pink&green"
val regex = "[,\\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
.onEach { println(it) }
.firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"
//sampleEnd
}
Аналогичная функция также была добавлена в CharSequence:
val mixedColor = colorsText.splitToSequence(regex)
Сериализация 1.3.0-RC
kotlinx.serialization 1.3.0-RC доступен с новыми возможностями JSON-сериализации:
Сериализация потоков Java IO
Управление значениями по умолчанию на уровне свойств
Возможность исключить нулевые значения из сериализации
Настраиваемые различатели классов в полиморфной сериализации
Подробнее в блоге изменений.
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew1530.html