Spec-Zone.ru › Kotlin 1.7

Что нового в 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 является Экспериментальной. Она может быть удалена или изменена в любое время. Требуется opt-in (см. подробности ниже), и ее следует использовать только в оценочных целях. Мы будем рады вашим отзывам на YouTrack.

Оператор исчерпывающий 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
        }
    }
}

Подвешенные функции в качестве супертипов

Поддержка подвешенных функций в качестве супертипов является Экспериментальной. Она может быть удалена или изменена в любое время. Требуется opt-in (см. подробности ниже), и ее следует использовать только в оценочных целях. Мы будем рады вашим отзывам на YouTrack.

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

Механизм opt-in является Экспериментальным. Он может быть изменен в любое время. См. как включить. Используйте только в оценочных целях. Мы будем рады вашим отзывам на YouTrack.

Автор библиотеки может пометить экспериментальный 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 с различными целевыми платформами

Механизм opt-in является Экспериментальным. Он может быть изменён в любое время. См. как включить. Используйте только в оценочных целях. Мы будем рады вашим отзывам на YouTrack.

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.

Создание экземпляров классов аннотаций

Создание экземпляров классов аннотаций — экспериментальная функция. Она может быть удалена или изменена в любое время. Требуется включение (см. подробности ниже), и её следует использовать только в оценочных целях. Мы будем признательны за ваши отзывы на эту функцию в YouTrack.

С 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. Обратите внимание, что все такие несоответствия нуллируемости по умолчанию являются предупреждениями.

END_OF_DOCUMENT_MARKER

Kotlin/Native

В Kotlin/Native произошли различные изменения и улучшения:

  • Поддержка Apple Silicon

  • Улучшенный Kotlin DSL для плагина CocoaPods Gradle

  • Экспериментальная взаимосвязь с 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:

  • macosArm64

  • iosSimulatorArm64

  • watchosSimulatorArm64

  • tvosSimulatorArm64

Они доступны как на хостах на базе 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 выберет необходимый тип сборки.

Нет необходимости объявлять конфигурации Debug и Release, так как они поддерживаются по умолчанию.

Экспериментальная взаимосвязь с Swift 5.5 async/await

Взаимосвязь асинхронности с Swift async/await является экспериментальной. Она может быть удалена или изменена в любое время. Вы должны использовать её только для оценочных целей. Мы будем благодарны за ваши отзывы на YouTrack.

Мы добавили поддержку вызова приостанавливающих функций 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 библиотек в совместном коде нативных платформ

  • Поддержка XCFrameworks

  • Новая настройка публикации по умолчанию для артефактов 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:

  • assembleXCFramework

  • assembleDebugXCFramework (дополнительно, артефакт отладки, содержащий 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

  • Улучшенная отладка приложений с бэкендом Kotlin/JS IR

Бэкенд компилятора 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-целей.

    Возможность установки параметра jdkHome напрямую устарела.

  • Устанавливает значение 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 с аргументами JVM.

Для получения дополнительной информации о демоне Kotlin см. демоне Kotlin и его использовании с Gradle.

END_OF_DOCUMENT_MARKER

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

Kotlin 1.5.30 привносит улучшения в API стандартной библиотеки Duration и Regex;

  • Изменение вывода Duration.toString()

  • Разбор Duration из строки

  • Сопоставление с Regex в определённой позиции

  • Разбиение Regex на последовательность

Изменение вывода Duration.toString()

API Duration является Экспериментальным. Он может быть удалён или изменён в любое время. Используйте его только в целях оценки. Мы будем признательны за ваши отзывы по этому поводу в YouTrack.

До Kotlin 1.5.30, функция Duration.toString() возвращала строковое представление своего аргумента, выраженное в единице, которая давала наиболее компактное и читаемое числовое значение. С этого момента она будет возвращать строковое значение, выраженное как комбинация числовых компонентов, каждый в своей собственной единице. Каждый компонент — это число, за которым следует сокращённое имя единицы: d, h, m, s. Например:

Пример вызова функции

Предыдущий вывод

Текущий вывод

Duration.days(45).toString()

45.0d

45d

Duration.days(1.5).toString()

36.0h

1d 12h

Duration.minutes(1230).toString()

20.5h

20h 30m

Duration.minutes(2415).toString()

40.3h

1d 16h 15m

Duration.minutes(920).toString()

920m

15h 20m

Duration.seconds(1.546).toString()

1.55s

1.546s

Duration.milliseconds(25.12).toString()

25.1ms

25.12ms

Способ представления отрицательных значений продолжительности также был изменён. Отрицательная продолжительность предваряется знаком минус (-), а если она состоит из нескольких компонентов, она заключается в скобки: -12m и -(1h 30m).

Обратите внимание, что малые промежутки времени менее одной секунды представляются одним числом с одной из субсекундных единиц. Например, ms (миллисекунды), us (микросекунды) или ns (наносекунды): 140.884ms, 500us, 24ns. Научная нотация больше не используется для их представления.

Если вы хотите выразить продолжительность в одной единице, используйте перегруженную функцию Duration.toString(unit, decimals).

Мы рекомендуем использовать Duration.toIsoString() в некоторых случаях, включая сериализацию и обмен данными. Duration.toIsoString() использует более строгий формат ISO-8601, а не Duration.toString().

Разбор Duration из строки

API Duration является Экспериментальным. Он может быть удалён или изменён в любое время. Используйте его только в целях оценки. Мы будем признательны за ваши отзывы по этому поводу в этом вопросе.

В Kotlin 1.5.30 в API Duration появились новые функции:

  • parse(), которая поддерживает разбор вывода:

    • toString().

    • toString(unit, decimals).

    • toIsoString().

  • 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() являются Экспериментальными. Они могут быть удалены или изменены в любое время. Используйте их только в целях оценки. Мы будем признательны за ваши отзывы по этому поводу в YouTrack.

Новые функции 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() и CharSequence.splitToSequence(Regex) являются Экспериментальными. Они могут быть удалены или изменены в любое время. Используйте их только в целях оценки. Мы будем признательны за ваши отзывы по этому поводу в YouTrack.

Новая функция 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 из сериализации

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

Узнайте больше в журнале изменений.

Последнее изменение: 06 сентября 2022
Что нового в Kotlin 1.6.0 Что нового в Kotlin 1.5.20

© 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

Spec-Zone.ru

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