Что нового в Kotlin 1.5.30
Дата выпуска: 24 августа 2021 года
Kotlin 1.5.30 предлагает обновления языка, включая предварительные версии будущих изменений, различные улучшения в поддержке платформы и инструментах, а также новые функции стандартной библиотеки.
Вот некоторые основные улучшения:
Возможности языка, включая экспериментальные запечатанные
whenоператоры, изменения в использовании требования opt-in и другиеПоддержка Apple silicon
Бета-версия бэкенда Kotlin/JS IR
Улучшенное взаимодействие с плагином Gradle
Вы также можете найти краткий обзор изменений в посте о выпуске и в этом видео:
Возможности языка
Kotlin 1.5.30 представляет предварительные версии будущих изменений языка и улучшения механизма opt-in и вывода типов:
Исчерпывающие операторы when для запечатанных и булевых выражений
Требование opt-in при неявном использовании экспериментальных API
Изменения в использовании аннотаций opt-in с различными целевыми платформами
Исчерпывающие операторы when для запечатанных и булевых выражений
Оператор исчерпывающий when содержит ветви для всех возможных типов или значений его объекта или для некоторых типов плюс else ветвь. Другими словами, он охватывает все возможные случаи.
Мы планируем вскоре запретить неисчерпывающие when операторы, чтобы сделать поведение согласованным с when выражениями. Чтобы обеспечить плавную миграцию, вы можете настроить компилятор на выдачу предупреждений о неисчерпывающих when операторах с запечатанным классом или булевым значением. Такие предупреждения будут отображаться по умолчанию в 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 для включения этой функции. Обратите внимание, что все текущие ограничения для классов аннотаций, такие как ограничения на определение параметров, отличных от вторичных конструкторов, или членов, остаются в силе.
Узнайте больше о создании экземпляров классов аннотаций в этом 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.
Ранее компилятор и инструменты Kotlin/Native требовали среду перевода Rosetta для работы на хостах с Apple silicon. В 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 фреймворков. В дополнение к имени фреймворка вы можете указать другие параметры в конфигурации pod:
Указать динамическую или статическую версию фреймворка
Явно включить экспорт зависимостей
Включить встраивание 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 для приостанавливающих функций с необязательными возвращаемыми типами. Это позволяет вызывать их из Swift как async функции с соответствующей необязательностью.
Обратите внимание, что эта функция экспериментальна и может быть изменена в будущем как в 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 Многоплатформенность предоставляет вам возможность использования платформ-зависимых библиотек межплатформенного взаимодействия в общих наборах исходных кодов. До версии 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
Используя плагин Gradle maven-publish, вы можете опубликовать свою многоплатформенную библиотеку для целевой платформы 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 достигает стадии Beta
Базовый бэкенд компилятора на основе IR для Kotlin/JS, который был представлен в 1.4.0 в стадии Alpha, достиг стадии Beta.
Ранее мы опубликовали руководство по миграции на бэкенд 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 toolchains, которая включает в себя возможность указать домашний каталог JDK с помощью интерфейса
UsesKotlinJavaToolchainдля более старых версий GradleБолее простой способ явно указать аргументы JVM для демона Kotlin
Поддержка Java toolchains
Gradle 6.7 представил функцию "Поддержка Java toolchains". Используя эту функцию, вы можете:
Выполнять компиляции, тесты и исполняемые файлы, используя JDK и JRE, отличные от Gradle.
Компилировать и тестировать код с невыпущенной версией языка.
С поддержкой toolchains, Gradle может автоматически определять локальные JDK и устанавливать отсутствующие JDK, необходимые Gradle для сборки. Теперь сам Gradle может работать на любом JDK и по-прежнему использовать функцию кэширования сборки build cache.
Плагин Kotlin Gradle поддерживает Java toolchains для задач компиляции Kotlin/JVM. Java toolchain:
-
Устанавливает параметр
jdkHome, доступный для JVM-целей. Устанавливает значение
kotlinOptions.jvmTargetна версию JDK toolchain, если пользователь явно не установил параметрjvmTarget. Если toolchain не настроен, полеjvmTargetиспользует значение по умолчанию. Узнайте больше о совместимости JVM-цели.Влияет на то, на каких JDK
kaptрабочие процессы выполняются.
Используйте следующий код для установки toolchain. Замените заполнитель <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"
}
}
Обратите внимание, что установка toolchain через расширение kotlin также обновит toolchain для задач компиляции Java.
Вы можете установить toolchain через расширение 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 toolchains вместо этого.
При использовании этой функции обратите внимание, что рабочие процессы kapt будут использовать только режим изоляции процесса, и свойство 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 в определённой позиции
Новые функции Regex.matchAt() и Regex.matchesAt() предоставляют способ проверить, имеет ли Regex точное совпадение в определённой позиции в 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 на последовательность
Новая функция Regex.splitToSequence() является ленивым аналогом split(). Она разделяет строку вокруг совпадений данного Regex, но возвращает результат в виде Sequence, так что все операции над этим результатом выполняются лениво.
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
Управление значениями по умолчанию на уровне свойств
Вариант исключения значений null из сериализации
Пользовательские дискриминаторы классов в полиморфной сериализации
Узнайте больше в журнале изменений.
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew1530.html