Spec-Zone.ru › Kotlin 1.8

Что нового в Kotlin 1.5.30

Дата выхода: 24 августа 2021 года

Kotlin 1.5.30 предлагает обновления языка, включая предварительные версии будущих изменений, различные улучшения поддержки платформ и инструментов, а также новые функции стандартной библиотеки.

Вот некоторые основные улучшения:

  • Функции языка, включая экспериментальные утверждения sealed when, изменения в использовании требования opt-in и другие

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

  • Бета-версия бэкенда Kotlin/JS IR

  • Улучшенная работа плагина Gradle

Вы также можете найти краткий обзор изменений в записи блога о выпуске и этом видео:

Особенности языка

Kotlin 1.5.30 предоставляет предварительные версии будущих изменений языка и вносит улучшения в механизм требования opt-in и вывод типов:

  • Исчерпывающие операторы when для sealed и Boolean

  • Функции-подвески в качестве супертипов

  • Требование opt-in при неявном использовании экспериментальных API

  • Изменения в использовании аннотаций требования opt-in с различными целевыми объектами

  • Улучшения вывода типов для рекурсивных обобщенных типов

  • Устранение ограничений вывода для билдеров

Исчерпывающие операторы when для sealed и Boolean

Поддержка исчерпывающих операторов when для sealed и Boolean-субъектов — экспериментальная. Она может быть удалена или изменена в любое время. Требуется opt-in (см. подробности ниже), и использовать ее следует только в оценочных целях. Мы будем благодарны за ваши отзывы на YouTrack.

Оператор исчерпывающий when содержит ветви для всех возможных типов или значений его объекта или для некоторых типов плюс else ветвь. Другими словами, он охватывает все возможные случаи.

Мы планируем вскоре запретить неполные when операторы, чтобы обеспечить согласованность с when выражениями. Для плавной миграции вы можете настроить компилятор на выдачу предупреждений о неполных when операторах с sealed классом или Boolean. Такие предупреждения будут появляться по умолчанию в Kotlin 1.6 и в дальнейшем будут считаться ошибками.

Для перечислений уже есть предупреждение.

sealed class Mode {
    object ON : Mode()
    object OFF : Mode()
}

fun main() {
    val x: Mode = Mode.ON
    when (x) { 
        Mode.ON -> println("ON")
    }
// WARNING: Non exhaustive 'when' statements on sealed classes/interfaces 
// will be prohibited in 1.7, add an 'OFF' or 'else' branch instead

    val y: Boolean = true
    when (y) {  
        true -> println("true")
    }
// WARNING: Non exhaustive 'when' statements on Booleans will be prohibited 
// in 1.7, add a 'false' or 'else' branch instead
}

Чтобы включить эту функцию в Kotlin 1.5.30, используйте версию языка 1.6. Вы также можете изменить предупреждения на ошибки, включив постепенный режим.

kotlin {
    sourceSets.all {
        languageSettings.apply {
            languageVersion = "1.6"
            //progressiveMode = true // false by default
        }
    }
}
kotlin {
    sourceSets.all {
        languageSettings {
            languageVersion = '1.6'
            //progressiveMode = true // false by default
        }
    }
}

Функции-подвески в качестве супертипов

Поддержка функций-подвесок в качестве супертипов — экспериментальная. Она может быть удалена или изменена в любое время. Требуется 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 — экспериментальный. Он может измениться в любое время. См., как включить 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 — экспериментальный. Он может измениться в любое время. См., как включить 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, чтобы включить эту функцию. Обратите внимание, что все текущие ограничения для классов аннотаций, такие как ограничения на определение параметров, отличных от вторичных конструкторов, или членов, не являющихся 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. Обратите внимание, что по умолчанию все такие несоответствия нулевости являются предупреждениями.

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.

Ранее для работы с хостами Apple Silicon компилятор и инструменты Kotlin/Native требовали среды перевода Rosetta. В 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. Помимо имени фреймворка, вы можете указать другие параметры в конфигурации под:

  • Укажите динамическую или статическую версию фреймворка

  • Включить явное экспорт зависимостей

  • Включить встраивание 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 для подвешенных функций с типом возвращаемого значения nullable. Это позволяет вызывать их из Swift как async функции с правильной маркировкой nullable.

Обратите внимание, что эта функция экспериментальная и может быть изменена в будущем как в Kotlin, так и в Swift. Пока мы предоставляем предварительный просмотр этой функции с определенными ограничениями, и с нетерпением ждем вашего отзыва. Узнайте больше о ее текущем состоянии и оставьте свой отзыв на этом вопросе в YouTrack.

Улучшенное отображение Swift/Objective-C для объектов и компаньонов

Теперь доступ к объектам и компаньонам может быть реализован более интуитивно для разработчиков нативных iOS. Например, если у вас есть следующие объекты в Kotlin:

object MyObject {
    val x = "Some value"
}

class MyClass {
    companion object {
        val x = "Some value"
    }
}

Чтобы получить к ним доступ в Swift, вы можете использовать свойства shared и companion:

MyObject.shared
MyObject.shared.x
MyClass.companion
MyClass.Companion.shared

Узнайте больше о совместимости Swift/Objective-C.

Устаревание связи с DLL без библиотек импорта для целей MinGW

LLD — это компоновщик из проекта LLVM, который мы планируем использовать в Kotlin/Native для целей MinGW из-за его преимуществ по сравнению с стандартным ld.bfd — в первую очередь, лучшей производительности.

Однако последняя стабильная версия LLD не поддерживает прямую связь с DLL для целей MinGW (Windows). Для такой связи требуется использование библиотек импорта. Хотя они не нужны с Kotlin/Native 1.5.30, мы добавляем предупреждение, чтобы проинформировать вас о том, что такое использование несовместимо с LLD, который в будущем станет стандартным компоновщиком для MinGW.

Пожалуйста, поделитесь своими мыслями и замечаниями о переходе к компоновщику LLD на этом вопросе на YouTrack.

Kotlin Многоплатформенная

1.5.30 содержит следующие заметные обновления для Kotlin Многоплатформенной:

  • Возможность использования пользовательских cinterop библиотек в совместном коде нативных платформ

  • Поддержка XCFrameworks

  • Новая настройка по умолчанию для публикации артефактов Android

Возможность использования пользовательских библиотек cinterop в совместном коде нативных платформ

Kotlin Многоплатформенная предоставляет возможность использования зависимых от платформы библиотек interop в общих наборах исходного кода. До версии 1.5.30 это работало только с библиотеками платформы, поставляемыми с Kotlin/Native. Начиная с 1.5.30, вы можете использовать свои пользовательские cinterop библиотеки. Для включения этой функции добавьте свойство kotlin.mpp.enableCInteropCommonization=true в свой gradle.properties:

kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
kotlin.mpp.enableCInteropCommonization=true

Поддержка XCFrameworks

Все проекты Kotlin Многоплатформенная теперь могут иметь XCFrameworks в качестве формата вывода. Apple представила XCFrameworks как замену универсальным (fat) фреймворкам. С помощью XCFrameworks вы:

  • Можете собрать логику для всех целевых платформ и архитектур в одном пакете.

  • Не нужно удалять все ненужные архитектуры перед публикацией приложения в App Store.

XCFrameworks полезно, если вы хотите использовать свой Kotlin фреймворк для устройств и симуляторов на Apple M1.

Для использования XCFrameworks обновите свой скрипт build.gradle(.kts):

import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

plugins {
    kotlin("multiplatform")
}

kotlin {
    val xcf = XCFramework()
  
    ios {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
    watchos {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
    tvos {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
}
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFrameworkConfig

plugins {
    id 'org.jetbrains.kotlin.multiplatform'
}

kotlin {
    def xcf = new XCFrameworkConfig(project)

    ios {
        binaries.framework {
            baseName = "shared"
            xcf.add(it)
        }
    }
    watchos {
        binaries.framework {
            baseName = "shared"
            xcf.add(it)
        }
    }
    tvos {
        binaries.framework {
            baseName = "shared"
            xcf.add(it)
        }
    }
}

При объявлении XCFrameworks будут зарегистрированы эти новые задачи Gradle:

  • assembleXCFramework

  • assembleDebugXCFramework (дополнительно артефакт отладки, содержащий dSYMs)

  • assembleReleaseXCFramework

Узнайте больше о XCFrameworks в этом видео WWDC.

Новая настройка по умолчанию для публикации артефактов Android

Используя плагин maven-publish Gradle, вы можете опубликовать свою многоплатформенную библиотеку для целевой платформы Android, указав имена вариантов Android в скрипте сборки. Плагин Kotlin Gradle сгенерирует публикации автоматически.

До версии 1.5.30 сгенерированная метаданные публикации метаданных содержали атрибуты типа сборки для каждого опубликованного варианта Android, что делало его совместимым только с тем же типом сборки, который используется потребителем библиотеки. Kotlin 1.5.30 вводит новую настройку по умолчанию для публикации:

  • Если все варианты Android, которые проект публикует, имеют одинаковый атрибут типа сборки, то опубликованные варианты не будут иметь атрибут типа сборки и будут совместимы с любым типом сборки.

  • Если опубликованные варианты имеют разные атрибуты типа сборки, то будут опубликованы только те, которые имеют значение release, без атрибута типа сборки. Это делает варианты релизов совместимыми с любым типом сборки на стороне потребителя, в то время как варианты не релизов будут совместимы только с соответствующими типами сборки потребителя.

Чтобы отказаться от этого и сохранить атрибуты типа сборки для всех вариантов, вы можете установить это свойство Gradle: kotlin.android.buildTypeAttribute.keep=true.

Kotlin/JS

В Kotlin/JS с версией 1.5.30 появились два основных улучшения:

  • Бета-версия компилятора JS IR бэкенда

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

Бета-версия компилятора JS IR бэкенда

Базовая часть компилятора на основе IR для Kotlin/JS, которая была представлена в 1.4.0 в Альфа версии, достигла стадии Бета.

Ранее мы опубликовали руководство по миграции для JS IR бэкенда, чтобы помочь вам мигрировать ваши проекты на новый бэкенд. Теперь мы хотим представить плагин IDE Kotlin/JS Inspection Pack, который отображает необходимые изменения прямо в IntelliJ IDEA.

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

Kotlin 1.5.30 добавляет генерацию JavaScript source map для Kotlin/JS IR бэкенда. Это улучшит опыт отладки Kotlin/JS при включенном IR бэкенде, с полной поддержкой отладки, включая точки останова, пошаговое выполнение и читаемые трассы стека с надлежащими ссылками на исходный код.

Узнайте, как отлаживать Kotlin/JS в браузере или IntelliJ IDEA Ultimate.

END_OF_DOCUMENT_MARKER

Gradle

В рамках нашей миссии по улучшению пользовательского опыта плагина Kotlin Gradle, мы реализовали следующие функции:

  • Поддержка Java-инструментариев, которая включает возможность указать домашний каталог JDK с помощью интерфейса UsesKotlinJavaToolchain для более старых версий Gradle

  • Более простой способ явно указать JVM-аргументы демона Kotlin

Поддержка Java-инструментариев

Gradle 6.7 ввёл функцию "Поддержка Java-инструментариев". Используя эту функцию, вы можете:

  • Выполнять компиляции, тесты и исполняемые файлы с использованием JDK и JRE, отличных от Gradle.

  • Компилировать и тестировать код с невыпущенной версией языка.

С поддержкой инструментариев Gradle может автоматически обнаруживать локальные JDK и устанавливать недостающие JDK, необходимые Gradle для сборки. Теперь сам Gradle может работать с любым JDK и по-прежнему использовать функцию кэширования сборки build cache.

Плагин Kotlin Gradle поддерживает Java-инструментарии для задач компиляции Kotlin/JVM. Java-инструментарий:

  • Устанавливает jdkHome параметр, доступный для целей JVM.

    Возможность прямого задания параметра jdkHome устарела.

  • Устанавливает kotlinOptions.jvmTarget на версию JDK инструментария, если пользователь не установил параметр jvmTarget явно. Если инструментарий не настроен, поле jvmTarget использует значение по умолчанию. Дополнительную информацию см. в соответствии JVM-целей.

  • Влияет на то, на каких JDK kapt рабочие процессы выполняются.

Используйте следующий код для установки инструментария. Замените заполнитель <MAJOR_JDK_VERSION> на версию JDK, которую вы хотите использовать:

kotlin {
    jvmToolchain {
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
    }
}
kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
    }
}

Обратите внимание, что установка инструментария через расширение kotlin также обновит инструментарий для задач компиляции Java.

Вы можете установить инструментарий через расширение java, и задачи компиляции Kotlin будут его использовать:

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
    }
}

Дополнительную информацию о настройке любой версии JDK для задач KotlinCompile см. в документации о установке версии JDK с помощью Task DSL.

Для версий Gradle с 6.1 по 6.6 используйте интерфейс UsesKotlinJavaToolchain для установки домашнего каталога JDK.

Установка домашнего каталога JDK с помощью интерфейса UsesKotlinJavaToolchain

Все задачи Kotlin, которые поддерживают установку JDK с помощью kotlinOptions, теперь реализуют интерфейс UsesKotlinJavaToolchain. Для установки домашнего каталога JDK укажите путь к вашему JDK и замените заполнитель <JDK_VERSION>:

project.tasks
    .withType<UsesKotlinJavaToolchain>()
    .configureEach {
        it.kotlinJavaToolchain.jdk.use(
            "/path/to/local/jdk",
            JavaVersion.<LOCAL_JDK_VERSION>
        )
    }
project.tasks
    .withType(UsesKotlinJavaToolchain.class)
    .configureEach {
        it.kotlinJavaToolchain.jdk.use(
            '/path/to/local/jdk',
            JavaVersion.<LOCAL_JDK_VERSION>
        )
    }

Для версий Gradle с 6.1 по 6.6 используйте интерфейс UsesKotlinJavaToolchain. Начиная с Gradle 6.7, используйте Java-инструментарии.

При использовании этой функции обратите внимание, что рабочие процессы задачи kapt будут использовать только режим изоляции процессов process isolation mode, и свойство kapt.workers.isolation будет игнорироваться.

Более простой способ явно указать JVM-аргументы демона Kotlin

В Kotlin 1.5.30 была реализована новая логика для JVM-аргументов демона Kotlin. Каждый из следующих параметров переопределяет предыдущие:

  • Если ничего не указано, демон Kotlin наследует аргументы от демона Gradle (как и прежде). Например, в файле gradle.properties:

    org.gradle.jvmargs=-Xmx1500m -Xms=500m
    
  • Если JVM-аргументы демона Gradle имеют системную переменную kotlin.daemon.jvm.options, используйте её как прежде:

    org.gradle.jvmargs=-Dkotlin.daemon.jvm.options=-Xmx1500m -Xms=500m
    
  • Вы можете добавить системную переменную kotlin.daemon.jvmargs в файл gradle.properties:

    kotlin.daemon.jvmargs=-Xmx1500m -Xms=500m
    
  • Вы можете указать аргументы в расширении kotlin:

    kotlin {
        kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
    }
    
    kotlin {
        kotlinDaemonJvmArgs = ["-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"]
    }
    
  • Вы можете указать аргументы для конкретной задачи:

    tasks
        .matching { it.name == "compileKotlin" && it is CompileUsingKotlinDaemon }
        .configureEach {
            (this as CompileUsingKotlinDaemon).kotlinDaemonJvmArguments.set(listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"))
        }
    
    tasks
        .matching {
            it.name == "compileKotlin" && it instanceof CompileUsingKotlinDaemon
        }
        .configureEach {
            kotlinDaemonJvmArguments.set(["-Xmx1g", "-Xms512m"])
        }
    

    В этом случае новый экземпляр демона Kotlin может запуститься при выполнении задачи. Дополнительную информацию см. в взаимодействии демона Kotlin с JVM-аргументами.

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

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

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

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

  • Парсинг Duration из строки

  • Сопоставление с регулярным выражением в определенной позиции

  • Разбиение регулярного выражения на последовательность

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

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

Новые функции Regex.matchAt() и Regex.matchesAt() позволяют проверить, есть ли точное соответствие регулярному выражению в определённой позиции в String или CharSequence.

matchesAt() возвращает логическое значение:

fun main(){
//sampleStart
    val releaseText = "Kotlin 1.5.30 is released!"
    // regular expression: one digit, dot, one digit, dot, one or more digits
    val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
    println(versionRegex.matchesAt(releaseText, 0)) // "false"
    println(versionRegex.matchesAt(releaseText, 7)) // "true"
//sampleEnd
}

matchAt() возвращает совпадение, если оно найдено, или null, если нет:

fun main(){
//sampleStart
    val releaseText = "Kotlin 1.5.30 is released!"
    val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
    println(versionRegex.matchAt(releaseText, 0)) // "null"
    println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
//sampleEnd
}

Разбиение регулярного выражения на последовательность

Функции Regex.splitToSequence() и CharSequence.splitToSequence(Regex) находятся в стадии экспериментальной разработки. Они могут быть удалены или изменены в любое время. Используйте их только для оценочных целей. Мы будем признательны за ваши отзывы на YouTrack.

Новая функция 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

  • Управление значениями по умолчанию на уровне свойств

  • Возможность исключить нулевые значения из сериализации

  • Настраиваемые различатели классов в полиморфной сериализации

Подробнее в блоге изменений.

Последнее изменение: 10 января 2023
Что нового в Kotlin 1.6.0 Что нового в Kotlin 1.5.20

© 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

Spec-Zone.ru

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