Spec-Zone.ru › Kotlin 1.6

Что нового в 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 и вывода типов:

  • Исчерпывающие выражения when для sealed и Boolean-субъектов

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

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

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

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

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

Исчерпывающие выражения when для sealed и Boolean-субъектов

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

Выражение 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
        }
    }
}

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

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

  • Запрещено помечать поля 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.

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

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

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. Когда Xcode выполняет процесс сборки Gradle, плагин 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 для приостанавливаемых функций с возвращаемыми значениями, которые могут быть 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.

END_OF_DOCUMENT_MARKER

Kotlin Multiplatform

1.5.30 содержит следующие заметные обновления для Kotlin Multiplatform:

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

  • Поддержка XCFrameworks

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

  • assembleXCFramework

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

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

В 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() возвращает 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() и 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

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

  • Вариант исключения нулевых значений из сериализации

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

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

Последнее изменение: 07 апреля 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