Spec-Zone.ru › Kotlin 1.7

Что нового в 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-записей

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

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

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

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

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

Они могут служить «внутренними» интерфейсами, которые нельзя реализовать вне того же модуля. Вы можете положиться на этот факт, например, для написания исчерпывающих 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) { }
    
  • В этом релизе мы изменили схему обработки имен для функций, чтобы исправить неправильное поведение.

    Начиная с 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.

Узнайте больше об inline-классах.

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).

Цель симулятора watchOS Apple 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-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, который включает некоторые новые функции:

  • Поддержка сериализации inline-классов

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

Поддержка сериализации inline-классов

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

@Serializable
inline class Color(val rgb: Int)

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

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

Подробнее в 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 документации.

Последнее изменение: 06 сентября 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