Spec-Zone.ru › Kotlin 1.6

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

Дата выпуска: 3 февраля 2021 года

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@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 мы выпустили прототип интерфейсов-печаток. Они дополняют классы-печатки и позволяют создавать более гибкие иерархии ограниченных классов.

Они могут служить «внутренними» интерфейсами, которые нельзя реализовать за пределами одного модуля. Это можно использовать, например, для написания исчерпывающих 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 продвигает встроенные классы до стадии Beta и вносит следующие функции и улучшения:

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

Для использования предварительной версии встроенных классов добавьте параметр компилятора -Xinline-classes или -language-version 1.5.

Дополнительную информацию об алгоритме модификации вы найдете в KEEP.

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

Kotlin/JVM

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

Бэкенд компилятора на основе IR для Kotlin/JVM, представленный в версии 1.4.0 в Альфа-стадии, достиг стадии Beta. Это последний предварительный стабильный уровень перед тем, как бэкенд на основе 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

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

В Kotlin/Native версии 1.4.30 внесены различные улучшения производительности, что привело к более быстрой компиляции. Например, время, необходимое для перестройки фреймворка в примере сети и хранения данных с 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.

END_OF_DOCUMENT_MARKER

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

Локально-независимый 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-в-код и Char-в-цифру

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

Текущие функции преобразования Char в числа, возвращающие коды UTF-16, выраженные в различных числовых типах, часто путают с аналогичным преобразованием String-в-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 документации.

Последнее изменение: 07 апреля 2022
Что нового в Kotlin 1.5.0 Что нового в Kotlin 1.4.20

© 2010–2022 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