Что нового в Kotlin 1.5.30
Kotlin 1.5.30 предлагает обновления языка, включая предварительные версии будущих изменений, различные улучшения поддержки платформы и инструментария, а также новые функции стандартной библиотеки.
Вот некоторые основные улучшения:
Функциональные возможности языка, включая экспериментальные условные (sealed)
whenоператоры, изменения в использовании требования opt-in и другие.Поддержка Apple silicon
Бета-версия Kotlin/JS IR-бекенда
Улучшенная работа плагина Gradle
Вы также можете найти краткий обзор изменений в статье в блоге о выпуске и этом видео:
Функции языка
Kotlin 1.5.30 предоставляет предварительные версии будущих изменений языка и улучшения механизма opt-in и вывода типов:
Исчерпывающие операторы when для условных (sealed) и булевых объектов
Требование opt-in для неявных использований экспериментальных API
Изменения в использовании аннотаций opt-in с различными целевыми объектами
Исчерпывающие операторы when для условных (sealed) и булевых объектов
Оператор исчерпывающий when содержит ветви для всех возможных типов или значений его объекта, или для некоторых типов плюс else ветвь. Другими словами, он охватывает все возможные случаи.
Мы планируем вскоре запретить неисчерпывающие when операторы, чтобы сделать поведение согласованным с when выражениями. Для обеспечения плавной миграции, вы можете настроить компилятор на выдачу предупреждений о неисчерпывающих when операторах с условным (sealed) классом или булевым значением. Такие предупреждения будут отображаться по умолчанию в 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-бекенде. Они представлены в нём как обычные функциональные типы с маркером интерфейса. Из-за маркера интерфейса невозможно определить, какие из суперинтерфейсов являются подвешенными (suspending), а какие — обычными.Вы не можете использовать несколько
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 5.5 async/await
Улучшенное отображение 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. При запуске Xcode процесса сборки Gradle плагин 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 для объектов и компаньонов
Доступ к объектам и компаньонам теперь можно получить более интуитивно для разработчиков native 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 Multiplatform
1.5.30 принесла следующие заметные обновления для Kotlin Multiplatform:
Возможность использования пользовательских
cinteropбиблиотек в общем нативном кодеНовая настройка публикации по умолчанию для артефактов Android
Возможность использования пользовательских библиотек cinterop в общем нативном коде
Kotlin Multiplatform предоставляет возможность использовать платформозависимые библиотеки межплатформенного взаимодействия в общих наборах исходного кода. До версии 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 Multiplatform теперь могут иметь 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 сгенерированный метаданные публикации metadata включал атрибуты типа сборки для каждого опубликованного варианта Android, что делало его совместимым только с тем же типом сборки, используемым потребителем библиотеки. Kotlin 1.5.30 вводит новую настройку публикации по умолчанию:
Если все варианты Android, которые проект публикует, имеют одинаковый атрибут типа сборки, опубликованные варианты не будут содержать атрибут типа сборки и будут совместимы с любым типом сборки.
Если опубликованные варианты имеют разные атрибуты типа сборки, будут опубликованы только те, которые имеют значение
release, без атрибута типа сборки. Это делает версии релизов совместимыми с любым типом сборки на стороне потребителя, в то время как нерелизные варианты будут совместимы только с соответствующими типами сборок потребителя.
Чтобы отказаться от этого и сохранить атрибуты типа сборки для всех вариантов, можно установить это свойство Gradle: kotlin.android.buildTypeAttribute.keep=true.
Kotlin/JS
В Kotlin/JS с версией 1.5.30 два основных улучшения:
Бета-версия компилятора JavaScript IR для Kotlin/JS
Основанный на IR компилятор для Kotlin/JS, который был представлен в 1.4.0 в Альфа-версии, достиг бета-стадии.
Ранее мы опубликовали руководство по миграции на JS IR backend, чтобы помочь вам мигрировать ваши проекты на новый backend. Теперь мы хотим представить плагин IDE Kotlin/JS Inspection Pack, который отображает необходимые изменения непосредственно в IntelliJ IDEA.
Улучшенный опыт отладки для приложений с Kotlin/JS IR backend
Kotlin 1.5.30 добавляет генерацию карт исходного кода JavaScript для Kotlin/JS IR backend. Это улучшит опыт отладки Kotlin/JS при включенном IR backend, с полной поддержкой отладки, включая точки останова, пошаговое выполнение и читаемые трассировки стека с правильными ссылками на исходный код.
Узнайте, как отлаживать 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 и по-прежнему использовать функцию кэширования сборки.
Kotlin Gradle плагин поддерживает Java инструмент-цепочки для задач компиляции Kotlin/JVM. Java инструмент-цепь:
-
Устанавливает значение параметра
jdkHome, доступного для целей JVM. Устанавливает значение
kotlinOptions.jvmTargetна версию JDK инструмент-цепи, если пользователь явно не установил параметрjvmTarget. Если инструмент-цепь не настроен, полеjvmTargetиспользует значение по умолчанию. Подробнее об совместимости JVM цели.Влияет на то, на каких JDK
kaptworker выполняются.
Используйте следующий код для установки инструмент-цепи. Замените <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>
)
}
Используйте интерфейс UsesKotlinJavaToolchain для версий Gradle от 6.1 до 6.6. Начиная с Gradle 6.7, используйте Java инструмент-цепочки.
При использовании этой функции обратите внимание, что kapt задачи worker будут использовать только режим изоляции процесса, а свойство 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 добавляет улучшения в стандартную библиотеку для Duration и Regex API:
Изменение вывода 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.
Regex.matchAt() возвращает логическое значение:
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
Управление значениями по умолчанию на уровне свойств
Опция исключения нулевых значений из сериализации
Настраиваемые дискриминаторы классов в полиморфной сериализации
Узнайте больше в блоге изменений.
© 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