Что нового в Kotlin 1.5.30
Дата выпуска: 24 августа 2021 года
Kotlin 1.5.30 предлагает обновления языка, включая предварительные версии будущих изменений, различные улучшения поддержки платформ и инструментария, а также новые функции стандартной библиотеки.
Вот некоторые основные улучшения:
Функции языка, включая экспериментальные sealed-выражения, изменения в требованиях opt-in и другие
Нативная поддержка Apple silicon
Бэкенд Kotlin/JS IR достиг стадии Beta
Улучшенный опыт работы с плагином Gradle
Вы также можете найти краткий обзор изменений в записи в блоге о выпуске и этом видео:
Функции языка
Kotlin 1.5.30 представляет предварительные версии будущих изменений языка и улучшения механизма opt-in и вывода типов:
Требование opt-in для неявных использований экспериментальных API
Изменения в использовании аннотаций opt-in с различными целевыми объектами
Исчерпывающие выражения when для sealed и Boolean-субъектов
Выражение when содержит ветви для всех возможных типов или значений его субъекта или для некоторых типов плюс when ветвь. Другими словами, оно охватывает все возможные случаи.
Мы планируем скоро запретить неисчерпывающие выражения 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 только если базовое объявление также помечено.
Запрещено помечать поля backing и геттеры. Можно помечать основное свойство вместо этого.
Запрещено устанавливать
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 для приостанавливаемых функций с возвращаемыми значениями, которые могут быть null. Это позволяет вызывать их из Swift как async функции с соответствующей информацией о возможном null.
Обратите внимание, что эта функция находится в стадии эксперимента и может быть изменена в будущем как в 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 Multiplatform
1.5.30 содержит следующие заметные обновления для Kotlin Multiplatform:
Возможность использования пользовательских
cinteropбиблиотек в общем коде для нативных платформНовая настройка публикации по умолчанию для артефактов Android
Возможность использования пользовательских библиотек cinterop в общем коде для нативных платформ
Kotlin Multiplatform предоставляет возможность использования зависимых от платформы библиотек 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 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 есть два основных улучшения:
Бета-версия бэкенда компилятора 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 для бэкенда 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 может работать на любом 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 будут использовать только режим изоляции процессов, и свойство 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() возвращает boolean-результат:
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–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew1530.html