Spec-Zone.ru › Kotlin 1.9

Что нового в Kotlin 1.4.30

Выпущено: 3 февраля 2021 года

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

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

Языковые функции

Kotlin 1.5.0 принесёт новые языковые функции – поддержку JVM-записей, интерфейсы-печати и стабильные встроенные классы. В Kotlin 1.4.30 вы можете опробовать эти функции и улучшения в режиме предварительного просмотра. Мы будем очень признательны, если вы поделитесь своими отзывами с нами в соответствующих билетах YouTrack, так как это позволит нам учесть их перед выпуском 1.5.0.

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

  • Интерфейсы-печати и улучшения для sealed class

  • Улучшенные встроенные классы

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

Узнайте больше о предварительном просмотре новых функций в этой статье блога.

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

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

Релиз JDK 16 включает планы по стабилизации нового типа класса Java под названием record. Для обеспечения всех преимуществ Kotlin и сохранения его межплатформенной совместимости с Java, Kotlin вводит экспериментальную поддержку классов-записей.

Вы можете использовать классы-записи, объявленные на Java, точно так же, как классы с свойствами в Kotlin. Дополнительных шагов не требуется.

Начиная с версии 1.4.30, вы можете объявлять классы-записи в Kotlin, используя аннотацию @JvmRecord для класса данных:

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

Чтобы попробовать предварительную версию JVM-записей, добавьте опции компилятора -Xjvm-enable-preview и -language-version 1.5.

Мы продолжаем работать над поддержкой JVM-записей, и мы будем очень признательны, если вы поделитесь своими отзывами с нами, используя этот билет YouTrack.

Узнайте больше о реализации, ограничениях и синтаксисе в KEEP.

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

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

В Kotlin 1.4.30 мы выпускаем прототип интерфейсов-печатей. Они дополняют sealed классы и позволяют создавать более гибкие иерархии ограниченных классов.

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

sealed interface Polygon

class Rectangle(): Polygon
class Triangle(): Polygon

// when() is exhaustive: no other polygon implementations can appear
// after the module is compiled
fun draw(polygon: Polygon) = when (polygon) {
    is Rectangle -> // ...
    is Triangle -> // ...
}

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

sealed interface Fillable {
   fun fill()
}
sealed interface Polygon {
   val vertices: List<Point>
}

class Rectangle(override val vertices: List<Point>): Fillable, Polygon {
   override fun fill() { /*...*/ }
}

Чтобы попробовать предварительную версию интерфейсов-печатей, добавьте опцию компилятора -language-version 1.5. После переключения на эту версию вы сможете использовать модификатор sealed для интерфейсов. Мы будем очень признательны, если вы поделитесь своими отзывами с нами, используя этот билет YouTrack.

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

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

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

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

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

Чтобы попробовать иерархии запечатанных классов в пакетах, добавьте опцию компилятора -language-version 1.5. Мы будем очень признательны, если вы поделитесь своими отзывами с нами, используя этот билет YouTrack.

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

Улучшенные встроенные классы

Встроенные классы значений находятся в стадии Бета. Они практически стабильны, но в будущем могут потребоваться шаги миграции. Мы сделаем всё возможное, чтобы свести к минимуму изменения, которые вам придётся внести. Мы будем благодарны за ваши отзывы по функции встроенных классов в YouTrack.

Kotlin 1.4.30 продвигает встроенные классы до стадии Бета и вносит следующие функции и улучшения:

  • Поскольку встроенные классы являются классами значений, вы можете определить их с помощью модификатора value. Модификаторы inline и value теперь эквивалентны друг другу. В будущих версиях Kotlin мы планируем устареть модификатор inline.

    Теперь Kotlin требует аннотацию @JvmInline перед объявлением класса для JVM-бекенда:

    inline class Name(private val s: String)
    
    value class Name(private val s: String)
    
    // For JVM backends
    @JvmInline
    value class Name(private val s: String)
    
  • Встроенные классы могут иметь init блоки. Вы можете добавить код, который будет выполнен сразу после создания экземпляра класса:

    @JvmInline
    value class Negative(val x: Int) {
      init {
          require(x < 0) { }
      }
    }
    
  • Вызов функций со встроенными классами из кода Java: до Kotlin 1.4.30, вы не могли вызывать функции, принимающие встроенные классы из Java из-за искажения имён. Теперь вы можете отключить искажение имён вручную. Для вызова таких функций из кода Java, вы должны добавить аннотацию @JvmName перед объявлением функции:

    inline class UInt(val x: Int)
    
    fun compute(x: Int) { }
    
    @JvmName("computeUInt")
    fun compute(x: UInt) { }
    
  • В этом релизе мы изменили схему искажения имён функций, чтобы исправить неправильное поведение. Эти изменения привели к изменениям ABI.

    Начиная с 1.4.30, компилятор Kotlin использует новую схему искажения имён по умолчанию. Используйте опцию компилятора -Xuse-14-inline-classes-mangling-scheme чтобы принудительно использовать старую схему искажения имён 1.4.0 и сохранить бинарную совместимость.

Kotlin 1.4.30 продвигает встроенные классы до стадии Бета, и мы планируем сделать их стабильными в будущих версиях. Мы будем очень признательны, если вы поделитесь своими отзывами с нами, используя этот билет YouTrack.

Чтобы попробовать предварительную версию встроенных классов, добавьте опцию компилятора -Xinline-classes или -language-version 1.5.

Узнайте больше об алгоритме искажения имён в KEEP.

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

Kotlin/JVM

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

Бэкенд компилятора на основе IR для Kotlin/JVM, представленный в 1.4.0 в альфа-версии, достиг бета-версии. Это последний до стабильной версии уровень перед тем, как бэкенд IR станет стандартным для компилятора Kotlin/JVM.

Теперь снято ограничение на использование бинарных файлов, сгенерированных компилятором IR. Ранее вы могли использовать код, скомпилированный новым бэкэндом JVM IR, только если вы включили новый бэкенд. Начиная с 1.4.30, такого ограничения больше нет, поэтому вы можете использовать новый бэкенд для создания компонентов для стороннего использования, таких как библиотеки. Попробуйте бета-версию нового бэкенда и поделитесь своими отзывами в нашем трекере проблем.

Чтобы включить новый бэкенд JVM IR, добавьте следующие строки в файл конфигурации проекта:

  • В Gradle:

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

    <configuration>
        <args>
            <arg>-Xuse-ir</arg>
        </args>
    </configuration>
    

Узнайте больше о изменениях, которые привносит бэкенд JVM IR, в этой статье блога.

Kotlin/Native

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

В 1.4.30 Kotlin/Native получил ряд улучшений производительности, что привело к более быстрому времени компиляции. Например, время, необходимое для повторной сборки фреймворка в примере сетевых операций и хранения данных с Kotlin Multiplatform Mobile, сократилось с 9,5 секунд (в 1.4.10) до 4,5 секунд (в 1.4.30).

Цель симулятора Apple watchOS 64-битный

Цель симулятора x86 была устаревшей для watchOS с версии 7.0. Для поддержки последних версий watchOS, Kotlin/Native имеет новую цель watchosX64 для запуска симулятора на 64-битной архитектуре.

Поддержка библиотек Xcode 12.2

Мы добавили поддержку новых библиотек, поставляемых с Xcode 12.2. Теперь вы можете использовать их из кода Kotlin.

Kotlin/JS

Ленивая инициализация свойств верхнего уровня

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

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

Мы продолжим работу над ленивой инициализацией, и просим вас попробовать текущий прототип и поделиться своими мыслями и результатами в этом YouTrack тикете или в канале #javascript в официальном Kotlin Slack (получить приглашение здесь).

Чтобы использовать ленивую инициализацию, добавьте параметр компилятора -Xir-property-lazy-initialization при компиляции кода с помощью компилятора JS IR.

Улучшения проектов Gradle

Поддержка кэша конфигурации Gradle

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

Чтобы начать использование этой функции, вы можете использовать команду Gradle или настроить IDE на основе IntelliJ.

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

Локализованно-независимый API для преобразования регистра текста

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

В этом релизе представлен экспериментальный локализованно-независимый API для изменения регистра строк и символов. Текущие toLowerCase(), toUpperCase(), capitalize(), decapitalize() функции API чувствительны к локали. Это означает, что разные настройки локали платформы могут влиять на поведение кода. Например, в турецкой локали при преобразовании строки «kotlin» с помощью toUpperCase, результатом будет «KOTLİN», а не «KOTLIN».

// current API
println("Needs to be capitalized".toUpperCase()) // NEEDS TO BE CAPITALIZED

// new API
println("Needs to be capitalized".uppercase()) // NEEDS TO BE CAPITALIZED

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

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

    Предыдущие версии

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

    String.toUpperCase()

    String.uppercase()

    String.toLowerCase()

    String.lowercase()

    String.capitalize()

    String.replaceFirstChar { it.uppercase() }

    String.decapitalize()

    String.replaceFirstChar { it.lowercase() }

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

    Предыдущие версии

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

    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.

Полный список изменений функций обработки текста можно найти на KEEP.

Четкое преобразование Char-to-код и Char-to-цифра

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

Текущие функции преобразования Char в числа, возвращающие коды UTF-16, выраженные в различных числовых типах, часто путают с аналогичным преобразованием String-to-Int, которое возвращает числовое значение строки:

"4".toInt() // returns 4
'4'.toInt() // returns 52
// and there was no common function that would return the numeric value 4 for Char '4'

Чтобы избежать этой путаницы, мы решили разделить преобразования 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
    

Дополнительные сведения см. в KEEP.

Обновления сериализации

Вместе с Kotlin 1.4.30 мы выпускаем kotlinx.serialization 1.1.0-RC, который включает некоторые новые функции:

  • Поддержка сериализации встроенных классов

  • Поддержка сериализации беззнаковых типов данных

Поддержка сериализации встроенных классов

Начиная с Kotlin 1.4.30, вы можете сделать встроенные классы сериализуемыми:

@Serializable
inline class Color(val rgb: Int)

Функция требует новый компилятор IR 1.4.30.

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

Подробнее см. в kotlinx.serialization документации.

Поддержка сериализации беззнаковых типов данных

Начиная с 1.4.30, вы можете использовать стандартные JSON-сериализаторы kotlinx.serialization для беззнаковых типов данных: UInt, ULong, UByte, и UShort:

@Serializable
class Counter(val counted: UByte, val description: String)
fun main() {
   val counted = 239.toUByte()
   println(Json.encodeToString(Counter(counted, "tries")))
}

Подробнее см. в kotlinx.serialization документации.

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

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

Spec-Zone.ru

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