Spec-Zone.ru › Kotlin 1.9

Что нового в Kotlin 1.5.0

Выпущено: 5 мая 2021 года

Kotlin 1.5.0 представляет новые возможности языка, стабильный IR-основанный JVM компиляторный бэкэнд, улучшения производительности и эволюционные изменения, такие как стабилизация экспериментальных функций и устаревание устаревших.

Вы также можете ознакомиться с обзором изменений в посте о выпуске.

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

Kotlin 1.5.0 предоставляет стабильные версии новых возможностей языка, представленных для предварительного просмотра в 1.4.30:

  • Поддержка JVM записей

  • Запечатанные интерфейсы и улучшения запечатанных классов

  • Встроенные классы

Подробные описания этих функций доступны в этой статье блога и на соответствующих страницах документации Kotlin.

Поддержка JVM записей

Java быстро развивается, и чтобы Kotlin оставался совместимым с ней, мы добавили поддержку одной из её последних функций – классы-записи.

Поддержка Kotlin для JVM записей включает двустороннюю совместимость:

  • В коде Kotlin вы можете использовать Java классы-записи как обычные классы со свойствами.

  • Чтобы использовать класс Kotlin как запись в Java-коде, сделайте его классом data и отметьте его аннотацией @JvmRecord.

@JvmRecord
data class User(val name: String, val age: Int)

Узнайте больше о использовании JVM записей в Kotlin.

Запечатанные интерфейсы

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

sealed interface Polygon

Вы можете полагаться на этот факт, например, для написания исчерпывающих when выражений.

fun draw(polygon: Polygon) = when (polygon) {
   is Rectangle -> // ...
   is Triangle -> // ...
   // else is not needed - all possible implementations are covered
}

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

class FilledRectangle: Polygon, Fillable

Узнайте больше о запечатанных интерфейсах.

Иерархии запечатанных классов в пакете

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

Прямые подклассы могут быть верхнего уровня или вложены внутри любого количества других именованных классов, именованных интерфейсов или именованных объектов.

Подклассы запечатанного класса должны иметь должным образом квалифицированное имя — они не могут быть локальными или анонимными объектами.

Узнайте больше об иерархиях запечатанных классов.

Встроенные классы

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

Встроенные классы можно объявлять с модификатором value перед именем класса:

value class Password(val s: String)

JVM бэкенд также требует специальной аннотации @JvmInline:

@JvmInline
value class Password(val s: String)

Модификатор inline теперь устарел с предупреждением.

Узнайте больше о встроенных классах.

Kotlin/JVM

Kotlin/JVM получил ряд улучшений, как внутренних, так и ориентированных на пользователя. Вот наиболее заметные из них:

  • Стабильный JVM IR бэкенд

  • Новый целевой JVM: 1.8 по умолчанию

  • SAM-адаптеры через invokedynamic

  • Лямбды через invokedynamic

  • Устаревание @JvmDefault и старых режимов Xjvm-default

  • Улучшения в обработке аннотаций нулевых значений

Стабильный JVM IR бэкенд

IR-основанный бэкенд для компилятора Kotlin/JVM теперь стабилен и включен по умолчанию.

Начиная с Kotlin 1.4.0, предварительные версии IR-основанного бэкенда были доступны для ознакомления, и теперь он является по умолчанию для версии языка 1.5. Старый бэкенд по-прежнему используется по умолчанию для более ранних версий языка.

Дополнительные сведения о преимуществах IR-бэкенда и его дальнейшем развитии можно найти в этой статье блога.

Если вам нужно использовать старый бэкенд в Kotlin 1.5.0, можно добавить следующие строки в файл конфигурации проекта:

  • В Gradle:

tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
  kotlinOptions.useOldBackend = true
}
tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) {
 kotlinOptions.useOldBackend = true
}
  • В Maven:

<configuration>
    <args>
        <arg>-Xuse-old-backend</arg>
    </args>
</configuration>

Новый целевой JVM: 1.8 по умолчанию

Теперь целевая версия для компиляций Kotlin/JVM по умолчанию — 1.8. Целевая версия 1.6 устарела.

Если вам нужен сборка для JVM 1.6, вы всё еще можете переключиться на эту целевую версию. Узнайте как:

  • в Gradle

  • в Maven

  • в компиляторе командной строки

SAM-адаптеры через invokedynamic

Kotlin 1.5.0 теперь использует динамические вызовы (invokedynamic) для компиляции преобразований SAM (Single Abstract Method):

  • Над любым выражением, если тип SAM — интерфейс Java

  • Над лямбдой, если тип SAM — Kotlin-функциональный интерфейс

Новая реализация использует LambdaMetafactory.metafactory(), и вспомогательные оберточные классы больше не генерируются во время компиляции. Это уменьшает размер JAR-файла приложения, что улучшает производительность запуска JVM.

Чтобы вернуться к старой схеме реализации, основанной на генерации анонимных классов, добавьте опцию компилятора -Xsam-conversions=class.

Узнайте, как добавить опции компилятора в Gradle, Maven и компилятор командной строки.

Лямбды через invokedynamic

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

Kotlin 1.5.0 добавляет экспериментальную поддержку компиляции обычных Kotlin-лямбд (которые не преобразуются в экземпляр функционального интерфейса) в динамические вызовы (invokedynamic). Реализация создаёт более лёгкие бинарные файлы, используя LambdaMetafactory.metafactory(), что эффективно генерирует необходимые классы во время выполнения. В настоящее время у неё есть три ограничения по сравнению с обычной компиляцией лямбд:

  • Лямбда, скомпилированная в invokedynamic, не сериализуется.

  • Вызов toString() для такой лямбды даёт менее читаемое строковое представление.

  • Экспериментальный reflect API не поддерживает лямбды, созданные с LambdaMetafactory.

Чтобы попробовать эту функцию, добавьте опцию компилятора -Xlambdas=indy. Мы будем признательны за ваши отзывы об этом с помощью этого YouTrack-тикета.

Узнайте, как добавить опции компилятора в Gradle, Maven и компиляторе командной строки.

Устаревание @JvmDefault и старых режимов Xjvm-default

До Kotlin 1.4.0 существовала аннотация @JvmDefault вместе с режимами -Xjvm-default=enable и -Xjvm-default=compatibility. Они служили для создания JVM-метода по умолчанию для любого конкретного неабстрактного члена в Kotlin-интерфейсе.

В Kotlin 1.4.0 мы представили новые Xjvm-default режимы, которые включают генерацию метода по умолчанию для всего проекта.

В Kotlin 1.5.0 мы устареваем @JvmDefault и старые режимы Xjvm-default: -Xjvm-default=enable и -Xjvm-default=compatibility.

Узнайте больше о методах по умолчанию в Java-совместимости.

Улучшения в обработке аннотаций нулевых значений

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

  • Он считывает аннотации нулевых значений для аргументов типов в скомпилированных Java-библиотеках, используемых в качестве зависимостей.

  • Он поддерживает аннотации нулевых значений с целевой версией TYPE_USE для:

    • Массивов

    • Varargs

    • Полей

    • Параметров типа и их ограничений

    • Аргументов типов базовых классов и интерфейсов

  • Если аннотация нулевых значений имеет несколько применимых к типу целей, и одна из этих целей — TYPE_USE, то TYPE_USE имеет приоритет. Например, сигнатура метода @Nullable String[] f() становится fun f(): Array<String?>!, если @Nullable поддерживает как TYPE_USE, так и METHOD в качестве целей.

В этих новых поддерживаемых случаях использование неправильного типа нулевых значений при вызове Java из Kotlin приводит к предупреждениям. Используйте опцию компилятора -Xtype-enhancement-improvements-strict-mode, чтобы включить строгий режим для этих случаев (с сообщением об ошибке).

Узнайте больше о безопасности при работе с нулевыми значениями и платформных типах.

Kotlin/Native

Kotlin/Native теперь более производительный и стабильный. Отличительные изменения:

  • Улучшения производительности

  • Отключение проверки утечек памяти

Улучшения производительности

В версии 1.5.0 Kotlin/Native получил набор улучшений производительности, ускоряющих как компиляцию, так и выполнение.

В режиме отладки теперь поддерживаются кэши компилятора для linuxX64 (только на хостах Linux) и целей iosArm64. При включенных кэшах компиляции, большинство отладочных компиляций завершаются значительно быстрее, за исключением первой. Измерения показали увеличение скорости на наших тестовых проектах примерно на 200%.

Чтобы использовать кэши компилятора для новых целей, добавьте следующие строки в gradle.properties проекта:

  • Для linuxX64: kotlin.native.cacheKind.linuxX64=static

  • Для iosArm64: kotlin.native.cacheKind.iosArm64=static

Если у вас возникнут проблемы после включения кэшей компилятора, пожалуйста, сообщите об этом в наш трекер ошибок YouTrack.

Другие улучшения ускоряют выполнение кода Kotlin/Native:

  • Тривиальные аксессоры свойств теперь инлайнизируются.

  • trimIndent() для строковых литералов вычисляется во время компиляции.

Отключение проверки утечек памяти

Встроенная проверка утечек памяти Kotlin/Native отключена по умолчанию.

Изначально она была разработана для внутреннего использования и способна находить утечки только в ограниченном числе случаев, а не во всех. Более того, позже выяснилось, что она может вызывать сбои приложения. Поэтому мы решили отключить проверку утечек памяти.

Проверка утечек памяти по-прежнему может быть полезной в определенных случаях, например, при тестировании. В таких случаях вы можете включить её, добавив следующую строку кода:

Platform.isMemoryLeakCheckerActive = true

Обратите внимание, что включение проверки для работы приложения не рекомендуется.

Kotlin/JS

В версии 1.5.0 Kotlin/JS претерпевает эволюционные изменения. Мы продолжаем работу над переходом бекенда компилятора JS IR к стабильной версии и вносим другие обновления:

  • Обновление webpack до версии 5

  • Фреймворки и библиотеки для компилятора IR

Обновление до webpack 5

Плагин Kotlin/JS Gradle теперь использует webpack 5 для целей браузера вместо webpack 4. Это значительное обновление webpack, которое вносит несовместимые изменения. Если вы используете пользовательскую конфигурацию webpack, обязательно ознакомьтесь с примечаниями к релизу webpack 5.

Подробнее о сборке проектов Kotlin/JS с помощью webpack.

Фреймворки и библиотеки для компилятора IR

Компилятор Kotlin/JS IR находится в стадии альфа-версии. Он может претерпевать несовместимые изменения и потребовать ручных миграций в будущем. Мы будем благодарны за ваши отзывы в YouTrack.

Вместе с разработкой бэкенда на основе IR для компилятора Kotlin/JS, мы поощряем и помогаем авторам библиотек создавать свои проекты в режиме both. Это означает, что они могут создавать артефакты для обоих компиляторов Kotlin/JS, тем самым расширяя экосистему для нового компилятора.

Многие известные фреймворки и библиотеки уже доступны для бэкенда IR: KVision, fritz2, doodle и другие. Если вы используете их в своём проекте, вы уже можете собрать его с помощью бэкенда IR и оценить его преимущества.

Если вы создаёте собственную библиотеку, соберите её в режиме «both», чтобы ваши клиенты также могли использовать её с новым компилятором.

Kotlin Multiplatform

В Kotlin 1.5.0 выбор зависимости для тестирования для каждой платформы был упрощён, и теперь выполняется автоматически плагином Gradle.

Новый API для получения категории символа теперь доступен в проектах multiplatform.

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

Стандартная библиотека получила ряд изменений и улучшений, от стабилизации экспериментальных частей до добавления новых функций:

  • Стабильные беззнаковые целочисленные типы

  • Стабильный API, не зависящий от локали, для перевода текста в верхний/нижний регистр

  • Стабильный API преобразования символа в целое число

  • Стабильный API пути

  • Деление с округлением вниз и оператор mod

  • Изменения в API Duration

  • Новый API для получения категории символа теперь доступен в многоплатформенном коде

  • Новая функция коллекций firstNotNullOf()

  • Строгая версия String?.toBoolean()

Вы можете узнать больше об изменениях в стандартной библиотеке в этом сообщении блога.

Стабильные беззнаковые целочисленные типы

UInt, ULong, UByte, UShort беззнаковые целочисленные типы теперь стабильны. То же самое относится к операциям над этими типами, диапазонами и их прогрессиями. Беззнаковые массивы и операции над ними остаются в бета-версии.

Узнайте больше о беззнаковых целочисленных типах.

Стабильный API, не зависящий от локали, для перевода текста в верхний/нижний регистр

Этот релиз включает новый API, не зависящий от локали, для преобразования текста в верхний/нижний регистр. Он предоставляет альтернативу функциям API toLowerCase(), toUpperCase(), capitalize() и decapitalize(), которые зависят от локали. Новый API помогает избежать ошибок из-за различных настроек локали.

Kotlin 1.5.0 предоставляет следующие полностью стабильные альтернативы:

  • Для функций String:

    Более ранние версии

    Альтернатива 1.5.0

    String.toUpperCase()

    String.uppercase()

    String.toLowerCase()

    String.lowercase()

    String.capitalize()

    String.replaceFirstChar { it.uppercase() }

    String.decapitalize()

    String.replaceFirstChar { it.lowercase() }

  • Для функций Char:

    Более ранние версии

    Альтернатива 1.5.0

    Char.toUpperCase()

    Char.uppercaseChar(): Char
    Char.uppercase(): String

    Char.toLowerCase()

    Char.lowercaseChar(): Char
    Char.lowercase(): String

    Char.toTitleCase()

    Char.titlecaseChar(): Char
    Char.titlecase(): String

Для Kotlin/JVM также существуют перегруженные функции uppercase(), lowercase() и titlecase() с явным параметром Locale.

Старые функции API помечены как устаревшие и будут удалены в будущей версии.

См. полный список изменений в функциях обработки текста в KEEP.

Стабильный API преобразования символа в целое число

Начиная с Kotlin 1.5.0, новые функции преобразования символа в код и символа в цифру являются стабильными. Эти функции заменяют текущие функции API, которые часто путали с похожим преобразованием строки в Int.

Новый API устраняет эту путаницу в именах, делая поведение кода более прозрачным и однозначным.

Этот релиз представляет преобразования Char, которые разделены на следующие наборы функций с четкими именами:

  • Функции для получения целочисленного кода Char и для построения Char из данного кода:

fun Char(code: Int): Char
fun Char(code: UShort): Char
val Char.code: Int
  • Функции для преобразования Char в числовое значение цифры, которую он представляет:

fun Char.digitToInt(radix: Int): Int
fun Char.digitToIntOrNull(radix: Int): Int?
  • Функция-расширение для Int для преобразования неотрицательной одиночной цифры, которую она представляет, в соответствующее представление Char:

fun Int.digitToChar(radix: Int): Char

Старые API преобразования, включая Number.toChar() с его реализациями (все, кроме Int.toChar()) и расширения Char для преобразования в числовой тип, такой как Char.toInt(), теперь устарели.

Узнайте больше об API преобразования символа в целое число в KEEP.

Стабильный API пути

Экспериментальный API пути с расширениями для java.nio.file.Path теперь стабилен.

// construct path with the div (/) operator
val baseDir = Path("/base")
val subDir = baseDir / "subdirectory"

// list files in a directory
val kotlinFiles: List<Path> = Path("/home/user").listDirectoryEntries("*.kt")

Узнайте больше о Path API.

Деление с округлением вниз и оператор mod

В стандартную библиотеку были добавлены новые операции для модульной арифметики:

  • floorDiv() возвращает результат деления с округлением вниз. Он доступен для целочисленных типов.

  • mod() возвращает остаток от деления с округлением вниз (модуль). Он доступен для всех числовых типов.

Эти операции очень похожи на существующие деление целых чисел и функцию rem() (или оператор %), но они работают по-разному с отрицательными числами:

  • a.floorDiv(b) отличается от обычного / тем, что floorDiv округляет результат вниз (к меньшему целому числу), тогда как / усекает результат до целого числа, ближайшего к 0.

  • a.mod(b) — это разница между a и a.floorDiv(b) * b. Она либо равна нулю, либо имеет тот же знак, что и b, тогда как a % b может иметь другой.

fun main() {
//sampleStart
    println("Floored division -5/3: ${(-5).floorDiv(3)}")
    println( "Modulus: ${(-5).mod(3)}")
    
    println("Truncated division -5/3: ${-5 / 3}")
    println( "Remainder: ${-5 % 3}")
//sampleEnd    
}

Изменения в API Duration

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

Существует экспериментальный класс Duration для представления продолжительности во времени в различных единицах измерения. В версии 1.5.0 API Duration претерпел следующие изменения:

  • Внутреннее представление значения теперь использует Long вместо Double для обеспечения большей точности.

  • Появился новый API для преобразования в определённую единицу измерения времени в Long. Он заменяет устаревший API, который работал с Double значениями и теперь устарел. Например, Duration.inWholeMinutes возвращает значение продолжительности, выраженное в Long и заменяет Duration.inMinutes.

  • Появились новые вспомогательные функции для построения Duration из числа. Например, Duration.seconds(Int) создаёт объект Duration, представляющий целое число секунд. Старые расширяемые свойства, такие как Int.seconds, теперь устарели.

import kotlin.time.Duration
import kotlin.time.ExperimentalTime

@ExperimentalTime
fun main() {
//sampleStart
    val duration = Duration.milliseconds(120000)
    println("There are ${duration.inWholeSeconds} seconds in ${duration.inWholeMinutes} minutes")
//sampleEnd
}

Новый API для получения категории символа, доступный в коде для нескольких платформ

Kotlin 1.5.0 представляет новый API для получения категории символа в соответствии с Unicode в проектах для нескольких платформ. Несколько функций теперь доступны на всех платформах и в общем коде.

Функции для проверки, является ли символ буквой или цифрой:

  • Char.isDigit()

  • Char.isLetter()

  • Char.isLetterOrDigit()

fun main() {
//sampleStart
    val chars = listOf('a', '1', '+')
    val (letterOrDigitList, notLetterOrDigitList) = chars.partition { it.isLetterOrDigit() }
    println(letterOrDigitList) // [a, 1]
    println(notLetterOrDigitList) // [+]
//sampleEnd    
}

Функции для проверки регистра символа:

  • Char.isLowerCase()

  • Char.isUpperCase()

  • Char.isTitleCase()

fun main() {
//sampleStart
    val chars = listOf('Dž', 'Lj', 'Nj', 'Dz', '1', 'A', 'a', '+')
    val (titleCases, notTitleCases) = chars.partition { it.isTitleCase() }
    println(titleCases) // [Dž, Lj, Nj, Dz]
    println(notTitleCases) // [1, A, a, +]
//sampleEnd    
}

Другие функции:

  • Char.isDefined()

  • Char.isISOControl()

Свойство Char.category и его перечисление типов возвращаемого значения CharCategory, которое указывает общую категорию символа в соответствии с Unicode, также доступны в проектах для нескольких платформ.

Узнайте больше о символах.

Новая функция для коллекций firstNotNullOf()

Новые функции firstNotNullOf() и firstNotNullOfOrNull() объединяют mapNotNull() с first() или firstOrNull(). Они отображают исходную коллекцию с пользовательской функцией-селектором и возвращают первое непустое значение. Если такого значения нет, firstNotNullOf() генерирует исключение, а firstNotNullOfOrNull() возвращает null.

fun main() {
//sampleStart
    val data = listOf("Kotlin", "1.5")
    println(data.firstNotNullOf(String::toDoubleOrNull))
    println(data.firstNotNullOfOrNull(String::toIntOrNull))
//sampleEnd
}

Строгая версия String?.toBoolean()

Две новые функции представляют собой строго контролируемые, регистронезависимые версии существующей функции String?.toBoolean():

  • String.toBooleanStrict() генерирует исключение для всех входных данных, кроме литералов true и false.

  • String.toBooleanStrictOrNull() возвращает null для всех входных данных, кроме литералов true и false.

fun main() {
//sampleStart
    println("true".toBooleanStrict())
    println("1".toBooleanStrictOrNull())
    // println("1".toBooleanStrict()) // Exception
//sampleEnd    
}

Библиотека kotlin-test

Библиотека kotlin-test вводит некоторые новые возможности:

  • Упрощенное использование зависимостей для тестов в многоплатформенных проектах

  • Автоматический выбор фреймворка для тестирования для наборов исходных кодов Kotlin/JVM

  • Обновления функций утверждений

Упрощенное использование зависимостей для тестов в многоплатформенных проектах

Теперь вы можете использовать зависимость kotlin-test для добавления зависимостей для тестирования в наборе исходных кодов commonTest, и плагин Gradle выведет соответствующие платформенные зависимости для каждого набора исходных кодов тестов:

  • kotlin-test-junit для наборов исходных кодов JVM, см. автоматический выбор фреймворка для тестирования для наборов исходных кодов Kotlin/JVM

  • kotlin-test-js для наборов исходных кодов Kotlin/JS

  • kotlin-test-common и kotlin-test-annotations-common для общих наборов исходных кодов

  • Нет дополнительных артефактов для наборов исходных кодов Kotlin/Native

Кроме того, вы можете использовать зависимость kotlin-test в любом общем или платформа-специфичном наборе исходных кодов.

Существующая настройка kotlin-test с явными зависимостями будет продолжать работать как в Gradle, так и в Maven.

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

Автоматический выбор фреймворка для тестирования для наборов исходных кодов Kotlin/JVM

Плагин Gradle теперь автоматически выбирает и добавляет зависимость от фреймворка для тестирования. Всё, что вам нужно сделать, это добавить зависимость kotlin-test в общий набор исходных кодов.

По умолчанию Gradle использует JUnit 4. Поэтому зависимость kotlin("test") разрешается до варианта для JUnit 4, а именно kotlin-test-junit:

kotlin {
    sourceSets {
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test")) // This brings the dependency
                                               // on JUnit 4 transitively
            }
        }
    }
}
kotlin {
    sourceSets {
        commonTest {
            dependencies {
                implementation kotlin("test") // This brings the dependency 
                                              // on JUnit 4 transitively
            }
        }
    }
}

Вы можете выбрать JUnit 5 или TestNG, вызвав useJUnitPlatform() или useTestNG() в задаче теста:

tasks {
    test {
        // enable TestNG support
        useTestNG()
        // or
        // enable JUnit Platform (a.k.a. JUnit 5) support
        useJUnitPlatform()
    }
}

Вы можете отключить автоматический выбор фреймворка для тестирования, добавив строку kotlin.test.infer.jvm.variant=false в файл gradle.properties проекта.

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

Обновления функций утверждений

Этот релиз добавляет новые функции утверждений и улучшает существующие.

Библиотека kotlin-test теперь имеет следующие возможности:

  • Проверка типа значения

    Вы можете использовать новые assertIs<T> и assertIsNot<T> для проверки типа значения:

    @Test
    fun testFunction() {
        val s: Any = "test"
        assertIs<String>(s)  // throws AssertionError mentioning the actual type of s if the assertion fails
        // can now print s.length because of contract in assertIs
        println("${s.length}")
    }
    

    Из-за стирания типов эта функция утверждения проверяет только, является ли value типом List в следующем примере, и не проверяет, является ли это списком определенного типа элемента String: assertIs<List<String>>(value).

  • Сравнение содержимого контейнера для массивов, последовательностей и произвольных итерируемых объектов

    Существует новый набор перегруженных функций assertContentEquals() для сравнения содержимого различных коллекций, которые не реализуют структурное равенство:

    @Test
    fun test() {
        val expectedArray = arrayOf(1, 2, 3)
        val actualArray = Array(3) { it + 1 }
        assertContentEquals(expectedArray, actualArray)
    }
    
  • Новые перегрузки для assertEquals() и assertNotEquals() для чисел Double и Float

    Существуют новые перегрузки для функции assertEquals(), которые позволяют сравнивать два числа Double или Float с абсолютной точностью. Значение точности указывается как третий параметр функции:

     @Test
    fun test() {
        val x = sin(PI)
    
        // precision parameter
        val tolerance = 0.000001
    
        assertEquals(0.0, x, tolerance)
    }
    
  • Новые функции для проверки содержимого коллекций и элементов

    Теперь вы можете проверить, содержит ли коллекция или элемент что-либо с помощью функции assertContains(). Вы можете использовать ее с коллекциями Kotlin и элементами, имеющими оператор contains(), такими как IntRange, String и другие:

    @Test
    fun test() {
        val sampleList = listOf<String>("sample", "sample2")
        val sampleString = "sample"
        assertContains(sampleList, sampleString)  // element in collection
        assertContains(sampleString, "amp")       // substring in string
    }
    
  • Функции assertTrue(), assertFalse(), expect() теперь являются встроенными

    Теперь вы можете использовать их как встроенные функции, поэтому вы можете вызывать функции suspend внутри лямбда-выражения:

    @Test
    fun test() = runBlocking<Unit> {
        val deferred = async { "Kotlin is nice" }
        assertTrue("Kotlin substring should be present") {
            deferred.await() .contains("Kotlin")
        }
    }
    

Библиотеки kotlinx

Вместе с Kotlin 1.5.0 мы выпускаем новые версии библиотек kotlinx:

  • kotlinx.coroutines 1.5.0-RC

  • kotlinx.serialization 1.2.1

  • kotlinx-datetime 0.2.0

Coroutines 1.5.0-RC

kotlinx.coroutines 1.5.0-RC с:

  • Новый API каналов

  • Стабильные реактивные интеграции

  • И многое другое

Начиная с Kotlin 1.5.0, экспериментальные coroutines отключены, и флаг -Xcoroutines=experimental больше не поддерживается.

Узнайте больше в блоге изменений и kotlinx.coroutines блоге выпуска 1.5.0.

Serialization 1.2.1

kotlinx.serialization 1.2.1 с:

  • Улучшения производительности сериализации JSON

  • Поддержка нескольких имен в сериализации JSON

  • Экспериментальная генерация схемы .proto из классов @Serializable

  • И многое другое

Узнайте больше в блоге изменений и kotlinx.serialization блоге выпуска 1.2.1.

dateTime 0.2.0

kotlinx-datetime 0.2.0 с:

  • @Serializable Объекты времени

  • Нормализованный API DateTimePeriod и DatePeriod

  • И многое другое

Узнайте больше в блоге изменений и kotlinx-datetime блоге выпуска 0.2.0.

END_OF_DOCUMENT_MARKER

Миграция на Kotlin 1.5.0

IntelliJ IDEA и Android Studio предложат обновить плагин Kotlin до 1.5.0, как только он станет доступен.

Для миграции существующих проектов на Kotlin 1.5.0, просто измените версию Kotlin на 1.5.0 и повторно импортируйте свой проект Gradle или Maven. Узнайте, как обновить до Kotlin 1.5.0.

Чтобы начать новый проект с Kotlin 1.5.0, обновите плагин Kotlin и запустите Мастер проектов из Файл | Новый | Проект.

Новый компилятор командной строки доступен для скачивания на странице выпусков GitHub.

Kotlin 1.5.0 является релизом с новыми функциями и, следовательно, может внести несовместимые изменения в язык. Подробный список таких изменений можно найти в Руководстве по совместимости для Kotlin 1.5.

Последнее изменение: 25 мая 2023 г.
Что нового в Kotlin 1.5.20 Что нового в Kotlin 1.4.30

© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew15.html

Spec-Zone.ru

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