Spec-Zone.ru › Kotlin 1.8

Что нового в Kotlin 1.7.20

Дата выпуска: 29 сентября 2022 года

Вышел релиз Kotlin 1.7.20! Вот некоторые важные моменты этого релиза:

  • Новый компилятор Kotlin K2 поддерживает all-open, SAM с получателем, Lombok и другие плагины компилятора

  • Мы представили предварительную версию оператора ..< для создания открытых диапазонов

  • Новый менеджер памяти Kotlin/Native теперь включен по умолчанию

  • Мы представили новую экспериментальную функцию для JVM: встроенные классы с универсальным базовым типом

Также вы можете найти краткий обзор изменений в этом видео:

Поддержка плагинов компилятора Kotlin K2

Команда Kotlin продолжает стабилизировать компилятор K2. K2 все еще находится в стадии Alpha (как было объявлено в релизе Kotlin 1.7.0), но теперь поддерживает несколько плагинов компилятора. Вы можете следить за обновлениями от команды Kotlin по новому компилятору в этой задаче в YouTrack.

Начиная с этого релиза 1.7.20, компилятор Kotlin K2 поддерживает следующие плагины:

  • all-open

  • no-arg

  • SAM с получателем

  • Lombok

  • AtomicFU

  • jvm-abi-gen

Альфа-версия нового компилятора K2 работает только с проектами JVM. Она не поддерживает Kotlin/JS, Kotlin/Native или другие кроссплатформенные проекты.

Узнайте больше о новом компиляторе и его преимуществах в следующих видео:

  • Путь к новому компилятору Kotlin

  • Компилятор K2: общий обзор

Как включить компилятор Kotlin K2

Чтобы включить компилятор Kotlin K2 и протестировать его, используйте следующий параметр компилятора:

-Xuse-k2

Вы можете указать его в вашем файле build.gradle(.kts):

tasks.withType<KotlinCompile> {
    kotlinOptions.useK2 = true
}
compileKotlin {
    kotlinOptions.useK2 = true
}

Проверьте повышение производительности в ваших проектах JVM и сравните результаты со старым компилятором.

Оставьте свой отзыв о новом компиляторе K2

Мы действительно ценим ваш отзыв в любой форме:

  • Поделитесь отзывом напрямую с разработчиками K2 в Kotlin Slack: получите приглашение и присоединитесь к каналу #k2-early-adopters.

  • Сообщите о проблемах, с которыми вы столкнулись при использовании нового компилятора K2, на нашей странице отслеживания проблем.

  • Включите опцию отправки статистических данных об использовании, чтобы разрешить JetBrains собирать анонимные данные об использовании K2.

Язык

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

  • Предварительный просмотр оператора ..< для создания открытых диапазонов

  • Новые объявления data object

  • Ограничения вывода типов билдеров

Предварительный просмотр оператора ..< для создания открытых диапазонов

Новый оператор является экспериментальным и имеет ограниченную поддержку в IDE.

Этот релиз вводит новый ..< оператор. В Kotlin есть .. оператор для выражения диапазона значений. Новый ..< оператор действует как функция until и помогает вам определить открытый диапазон.

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

Вот пример использования оператора ..< в выражении when:

when (value) {
    in 0.0..<0.25 -> // First quarter
    in 0.25..<0.5 -> // Second quarter
    in 0.5..<0.75 -> // Third quarter
    in 0.75..1.0 ->  // Last quarter  <- Note closed range here
}

Изменения API стандартной библиотеки

В следующих новых типах и операциях будут представлены в пакетах kotlin.ranges в стандартной библиотеке Kotlin:

Новый интерфейс OpenEndRange

Новый интерфейс для представления открытых диапазонов очень похож на существующий интерфейс ClosedRange<T>:

interface OpenEndRange<T : Comparable<T>> {
    // Lower bound
    val start: T
    // Upper bound, not included in the range
    val endExclusive: T
    operator fun contains(value: T): Boolean = value >= start && value < endExclusive
    fun isEmpty(): Boolean = start >= endExclusive
}
Реализация OpenEndRange в существующих итерируемых диапазонах

Когда разработчикам нужно получить диапазон с исключённой верхней границей, они в настоящее время используют функцию until для эффективного создания закрытого итерируемого диапазона с теми же значениями. Для того, чтобы сделать эти диапазоны приемлемыми в новой API, которая принимает OpenEndRange<T>, мы хотим реализовать этот интерфейс в существующих итерируемых диапазонах: IntRange, LongRange, CharRange, UIntRange и ULongRange. Таким образом, они будут одновременно реализовывать как интерфейс ClosedRange<T>, так и OpenEndRange<T>.

class IntRange : IntProgression(...), ClosedRange<Int>, OpenEndRange<Int> {
    override val start: Int
    override val endInclusive: Int
    override val endExclusive: Int
}
Операторы rangeUntil для стандартных типов

rangeUntil операторы будут предоставлены для тех же типов и комбинаций, которые в настоящее время определяются оператором rangeTo. Мы предоставляем их в качестве расширяющих функций для прототипирования, но для согласованности планируем сделать их членами позже, перед стабилизацией API открытых диапазонов.

Как включить оператор ..<

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

Новые элементы API, введённые для поддержки открытых диапазонов стандартных типов, требуют включения по выбору, как обычно для экспериментальной API stdlib: @OptIn(ExperimentalStdlibApi::class). В качестве альтернативы, можно использовать опцию компилятора -opt-in=kotlin.ExperimentalStdlibApi.

Подробнее об этом новом операторе в документе KEEP.

Улучшенные строковые представления для одиночных элементов и иерархий sealed-классов с data object

Data object являются экспериментальными и в настоящее время имеют ограниченную поддержку в IDE.

В этом релизе вводится новый тип объявления object для использования: data object. Data object концептуально идентичен обычному объявленному object, но поставляется со строковым представлением toString сразу же по умолчанию.

package org.example
object MyObject
data object MyDataObject

fun main() {
    println(MyObject) // org.example.MyObject@1f32e575
    println(MyDataObject) // MyDataObject
}

Это делает объявления data object идеальными для иерархий sealed-классов, где их можно использовать наряду с объявлениями data class. В этом фрагменте, объявление EndOfFile как data object вместо простого object означает, что оно получит красивое toString представление без необходимости ручной переопределения, сохраняя симметрию с соответствующими определениями data class:

sealed class ReadResult {
    data class Number(val value: Int) : ReadResult()
    data class Text(val value: String) : ReadResult()
    data object EndOfFile : ReadResult()
}

fun main() {
    println(ReadResult.Number(1)) // Number(value=1)
    println(ReadResult.Text("Foo")) // Text(value=Foo)
    println(ReadResult.EndOfFile) // EndOfFile
}

Как включить data object

Чтобы использовать объявления data object в своем коде, включите опцию компилятора -language-version 1.9. В проекте Gradle это можно сделать, добавив следующее в свой build.gradle(.kts):

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
    // ...
    kotlinOptions.languageVersion = "1.9"
}
compileKotlin {
    // ...
    kotlinOptions.languageVersion = '1.9'
}

Подробнее о data object и поделитесь своими отзывами об их реализации в соответствующем документе KEEP.

Новые ограничения вывода типов билдеров

Kotlin 1.7.20 накладывает некоторые значительные ограничения на использование вывода типов билдеров, которые могут повлиять на ваш код. Эти ограничения касаются кода, содержащего лямбда-функции билдера, где невозможно вывести параметр без анализа самой лямбды. Параметр используется в качестве аргумента. Теперь компилятор всегда будет показывать ошибку для такого кода и попросит вас явно указать тип.

Это изменение, вносящее разрыв в совместимости, но наши исследования показывают, что такие случаи очень редки, и ограничения не должны повлиять на ваш код. Если они повлияют, рассмотрите следующие случаи:

  • Вывод типа билдера с расширением, скрывающим члены.

    Если ваш код содержит функцию расширения с тем же именем, которая будет использована во время вывода типа билдера, компилятор покажет ошибку:

    class Data {
        fun doSmth() {} // 1
    }
    
    fun <T> T.doSmth() {} // 2
    
    fun test() {
        buildList {
            this.add(Data())
            this.get(0).doSmth() // Resolves to 2 and leads to error
        }
    }
    

    Для исправления кода необходимо явно указать тип:

    class Data {
        fun doSmth() {} // 1
    }
    
    fun <T> T.doSmth() {} // 2
    
    fun test() {
        buildList<Data> { // Type argument!
            this.add(Data())
            this.get(0).doSmth() // Resolves to 1
        }
    }
    
  • Вывод типа билдера с несколькими лямбдами и аргументы типа не указаны явно.

    Если в выводе типа билдера есть два или более блоков лямбда, они влияют на тип. Для предотвращения ошибки компилятор требует указать тип:

    fun <T: Any> buildList(
        first: MutableList<T>.() -> Unit, 
        second: MutableList<T>.() -> Unit
    ): List<T> {
        val list = mutableListOf<T>()
        list.first()
        list.second()
        return list 
    }
    
    fun main() {
        buildList(
            first = { // this: MutableList<String>
                add("")
            },
            second = { // this: MutableList<Int> 
                val i: Int = get(0)
                println(i)
            }
        )
    }
    

    Для исправления ошибки необходимо явно указать тип и исправить несоответствие типов:

    fun main() {
        buildList<Int>(
            first = { // this: MutableList<Int>
                add(0)
            },
            second = { // this: MutableList<Int>
                val i: Int = get(0)
                println(i)
            }
        )
    }
    

Если вы не нашли свой случай в приведенных выше примерах, создайте проблему в нашей команде.

См. эту задачу YouTrack для получения дополнительной информации об этом обновлении вывода типов билдеров.

Kotlin/JVM

Kotlin 1.7.20 вводит обобщённые inline-классы, добавляет больше оптимизаций байткода для делегируемых свойств и поддерживает IR в задаче генерации подстановочных файлов kapt, что позволяет использовать все самые новые возможности Kotlin с kapt:

  • Обобщённые inline-классы

  • Более оптимизированные случаи делегируемых свойств

  • Поддержка JVM IR-бекенда в задаче генерации подстановочных файлов kapt

Обобщённые inline-классы

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

Kotlin 1.7.20 позволяет базовому типу JVM inline-класса быть параметром типа. Компилятор отображает его на Any? или, вообще, на верхнюю границу параметра типа.

Рассмотрим следующий пример:

@JvmInline
value class UserId<T>(val value: T)

fun compute(s: UserId<String>) {} // Compiler generates fun compute-<hashcode>(s: Any?)

Функция принимает inline-класс в качестве параметра. Параметр отображается на верхнюю границу, а не на аргумент типа.

Чтобы включить эту функцию, используйте опцию компилятора -language-version 1.8.

Мы будем признательны за ваши отзывы на эту функцию в YouTrack.

Более оптимизированные случаи делегируемых свойств

В Kotlin 1.6.0 мы оптимизировали случай делегирования свойству, опуская поле $delegate и генерируя непосредственный доступ к целевому свойству. В 1.7.20 мы реализовали эту оптимизацию для большего количества случаев. Поле $delegate теперь будет опущено, если делегат является:

  • Именованным объектом:

    object NamedObject {
        operator fun getValue(thisRef: Any?, property: KProperty<*>): String = ...
    }
    
    val s: String by NamedObject
    
  • Заключительным val свойством с полем-экземпляром и по умолчанию getter-ом в том же модуле:

    val impl: ReadOnlyProperty<Any?, String> = ...
    
    class A {
        val s: String by impl
    }
    
  • Константным выражением, элементом перечисления, this или null. Вот пример this:

    class A {
        operator fun getValue(thisRef: Any?, property: KProperty<*>) ...
    
        val s by this
    }
    

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

Мы будем признательны за ваши отзывы на эту функцию в YouTrack.

Поддержка JVM IR-бекенда в задаче генерации подстановочных файлов kapt

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

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

Чтобы использовать IR-бекенд в kapt, добавьте следующую опцию в свой файл gradle.properties:

kapt.use.jvm.ir=true

Мы будем признательны за ваши отзывы на эту функцию в YouTrack.

Kotlin/Native

Kotlin 1.7.20 поставляется с новым менеджером памяти Kotlin/Native, включенным по умолчанию, и предоставляет возможность настроить файл Info.plist:

  • Новый менеджер памяти по умолчанию

  • Настройка файла Info.plist

Новый менеджер памяти Kotlin/Native по умолчанию

Этот релиз приносит дальнейшую стабильность и улучшения производительности новому менеджеру памяти, позволяя нам продвинуть новый менеджер памяти до Бета-версии.

Предыдущий менеджер памяти усложнял написание конкурентного и асинхронного кода, включая проблемы с реализацией библиотеки kotlinx.coroutines. Это препятствовало принятию Kotlin Multiplatform Mobile, так как ограничения по конкурентности создавали проблемы с совместным использованием Kotlin-кода между платформами iOS и Android. Новый менеджер памяти, наконец, открывает путь к выпуску Kotlin Multiplatform Mobile в бета-версии.

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

Настройка

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

Если вы уже включили его вручную, вы можете удалить опцию kotlin.native.binary.memoryModel=experimental из вашего файла gradle.properties или binaryOptions["memoryModel"] = "experimental" из файла build.gradle(.kts).

При необходимости вы можете вернуться к устаревшему менеджеру памяти с помощью опции kotlin.native.binary.memoryModel=strict в вашем файле gradle.properties. Однако, поддержка кэша компилятора больше недоступна для устаревшего менеджера памяти, поэтому время компиляции может ухудшиться.

Замораживание

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

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

  • Добавьте аннотацию к использованию устаревшего API с помощью @OptIn(FreezingIsDeprecated::class).

  • Примените languageSettings.optIn("kotlin.native.FreezingIsDeprecated") ко всем наборам исходного кода Kotlin в Gradle.

  • Передайте флаг компилятора -opt-in=kotlin.native.FreezingIsDeprecated.

Вызов Kotlin-функций приостановки из Swift/Objective-C

Новый менеджер памяти все еще ограничивает вызов Kotlin-функций suspend из Swift и Objective-C из потоков, отличных от основного, но вы можете снять это ограничение с помощью новой опции Gradle.

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

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

kotlin.native.binary.objcExportSuspendFunctionLaunchThreadRestriction=none

Не добавляйте эту опцию, если вы используете версию native-mt kotlinx.coroutines или других библиотек, которые имеют тот же подход «отправка в исходный поток».

Команда Kotlin выражает огромную благодарность Ахмеду Эль-Хелви за реализацию этой опции.

Оставьте свой отзыв

Это существенное изменение в нашей экосистеме. Мы будем рады вашим отзывам, чтобы сделать ее еще лучше.

Попробуйте новый менеджер памяти в своих проектах и оставьте свой отзыв в нашем трекере задач YouTrack.

Настройка файла Info.plist

При создании фреймворка компилятор Kotlin/Native генерирует файл свойств Info.plist, Info.plist. Раньше настройка его содержимого было сложно. С Kotlin 1.7.20 вы можете напрямую задать следующие свойства:

Свойство

Бинарный вариант

CFBundleIdentifier

bundleId

CFBundleShortVersionString

bundleShortVersionString

CFBundleVersion

bundleVersion

Для этого используйте соответствующий бинарный вариант. Передайте флаг компилятора -Xbinary=$option=$value или установите DSL Gradle binaryOption(option, value) для необходимого фреймворка.

Команда Kotlin выражает огромную благодарность Мадсу Агеру за реализацию этой функции.

Kotlin/JS

Kotlin/JS получил ряд улучшений, которые повышают удобство разработки и ускоряют производительность:

  • Генерация Klib стала быстрее как в инкрементальных, так и в чистых сборках благодаря улучшениям эффективности загрузки зависимостей.

  • Инкрементальная компиляция для библиотек разработки была переработана, что привело к существенным улучшениям в сценариях чистой сборки, более быстрым инкрементальным сборкам и исправлениям стабильности.

  • Мы улучшили генерацию .d.ts для вложенных объектов, sealed-классов и необязательных параметров в конструкторах.

Gradle

Обновления плагина Kotlin Gradle сосредоточены на совместимости с новыми функциями Gradle и последними версиями Gradle.

Kotlin 1.7.20 содержит изменения для поддержки Gradle 7.1. Устаревшие методы и свойства были удалены или заменены, что уменьшило количество предупреждений об устаревании, выводимых плагином Kotlin Gradle, и открывает путь к будущей поддержке Gradle 8.0.

Однако есть некоторые потенциально критические изменения, которые могут потребовать вашего внимания:

Настройка целевой платформы

  • org.jetbrains.kotlin.gradle.dsl.SingleTargetExtension теперь имеет параметр типа, SingleTargetExtension<T : KotlinTarget>.

  • Конвенция kotlin.targets.fromPreset() устарела. Вместо этого вы все еще можете использовать kotlin.targets { fromPreset() }, но мы рекомендуем использовать более специализированные способы создания целей.

  • Автоматически сгенерированные Gradle-доступы к целевым платформам больше недоступны внутри блока kotlin.targets { }. Используйте метод findByName("targetName") вместо этого.

    Обратите внимание, что такие вспомогательные функции все еще доступны в случае kotlin.targets, например, kotlin.targets.linuxX64.

Настройка директорий исходных кодов

Плагин Kotlin Gradle теперь добавляет Kotlin SourceDirectorySet как расширение kotlin к группе Java SourceSet. Это позволяет настроить директории исходных кодов в файле build.gradle.kts аналогично тому, как они настраиваются в Java, Groovy и Scala:

sourceSets {
    main {
        kotlin {
            java.setSrcDirs(listOf("src/java"))
            kotlin.setSrcDirs(listOf("src/kotlin"))
        }
    }
}

Вам больше не нужно использовать устаревшую конвенцию Gradle и указывать директории исходных кодов для Kotlin.

Помните, что вы также можете использовать расширение kotlin для доступа к KotlinSourceSet:

kotlin {
    sourceSets {
        main {
        // ...
        }
    }
}

Новый метод конфигурации JVM-инструментария

Этот релиз предоставляет новый метод jvmToolchain() для включения функции JVM-инструментария. Если вам не нужны дополнительные поля конфигурации, такие как implementation или vendor, вы можете использовать этот метод из расширения Kotlin:

kotlin {
    jvmToolchain(17)
}

Это упрощает процесс настройки проекта Kotlin без дополнительной конфигурации. До этого релиза вы могли указывать версию JDK только следующим образом:

kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}
END_OF_DOCUMENT_MARKER ```

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

Kotlin 1.7.20 предлагает новые расширяющие функции для класса java.nio.file.Path, что позволяет вам обходить древовидную структуру файлов:

  • walk() лениво обходит древовидную структуру файлов, укоренённую в указанном пути.

  • fileVisitor() позволяет создать FileVisitor отдельно. FileVisitor определяет действия над каталогами и файлами при их обходе.

  • visitFileTree(fileVisitor: FileVisitor, ...) потребляет готовое FileVisitor и использует java.nio.file.Files.walkFileTree() под капотом.

  • visitFileTree(..., builderAction: FileVisitorBuilder.() -> Unit) создаёт FileVisitor с builderAction и вызывает функцию visitFileTree(fileVisitor, ...).

  • FileVisitResult, тип возвращаемого значения FileVisitor, имеет значение по умолчанию CONTINUE, которое продолжает обработку файла.

Новые расширяющие функции для java.nio.file.Path являются Экспериментальными. Они могут быть изменены в любое время. Требуется явное включение (см. детали ниже), и их следует использовать только в оценочных целях.

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

  • Явно создайте FileVisitor, а затем используйте:

    val cleanVisitor = fileVisitor {
        onPreVisitDirectory { directory, attributes ->
            // Some logic on visiting directories
            FileVisitResult.CONTINUE
        }
    
        onVisitFile { file, attributes ->
            // Some logic on visiting files
            FileVisitResult.CONTINUE
        }
    }
    
    // Some logic may go here
    
    projectDirectory.visitFileTree(cleanVisitor)
    
  • Создайте FileVisitor с builderAction и используйте его немедленно:

    projectDirectory.visitFileTree {
    // Definition of the builderAction:
        onPreVisitDirectory { directory, attributes ->
            // Some logic on visiting directories
            FileVisitResult.CONTINUE
        }
    
        onVisitFile { file, attributes ->
            // Some logic on visiting files
            FileVisitResult.CONTINUE
        }
    }
    
  • Пройдитесь по древовидной структуре файлов, укоренённой в указанном пути, с помощью функции walk():

    @OptIn(kotlin.io.path.ExperimentalPathApi::class)
    fun traverseFileTree() {
        val cleanVisitor = fileVisitor {
            onPreVisitDirectory { directory, _ ->
                if (directory.name == "build") {
                    directory.toFile().deleteRecursively()
                    FileVisitResult.SKIP_SUBTREE
                } else {
                    FileVisitResult.CONTINUE
                }
            }
    
            onVisitFile { file, _ ->
                if (file.extension == "class") {
                    file.deleteExisting()
                }
                FileVisitResult.CONTINUE
            }
        }
    
        val rootDirectory = createTempDirectory("Project")
    
        rootDirectory.resolve("src").let { srcDirectory ->
            srcDirectory.createDirectory()
            srcDirectory.resolve("A.kt").createFile()
            srcDirectory.resolve("A.class").createFile()
        }
    
        rootDirectory.resolve("build").let { buildDirectory ->
            buildDirectory.createDirectory()
            buildDirectory.resolve("Project.jar").createFile()
        }
    
    
    // Use walk function:
        val directoryStructure = rootDirectory.walk(PathWalkOption.INCLUDE_DIRECTORIES)
            .map { it.relativeTo(rootDirectory).toString() }
            .toList().sorted()
        assertPrints(directoryStructure, "[, build, build/Project.jar, src, src/A.class, src/A.kt]")
    
        rootDirectory.visitFileTree(cleanVisitor)
    
        val directoryStructureAfterClean = rootDirectory.walk(PathWalkOption.INCLUDE_DIRECTORIES)
            .map { it.relativeTo(rootDirectory).toString() }
            .toList().sorted()
        assertPrints(directoryStructureAfterClean, "[, src, src/A.kt]")
    //sampleEnd
    }
    

Как обычно для экспериментального API, новые расширения требуют явного включения: @OptIn(kotlin.io.path.ExperimentalPathApi::class) или @kotlin.io.path.ExperimentalPathApi. В качестве альтернативы, вы можете использовать опцию компилятора: -opt-in=kotlin.io.path.ExperimentalPathApi.

Мы будем признательны за ваш отзыв по функции walk() и расширяющим функциям visit в YouTrack.

Обновления документации

С момента предыдущей версии документация Kotlin претерпела некоторые значительные изменения:

Переработанные и улучшенные страницы

  • Обзор основных типов – узнайте о базовых типах, используемых в Kotlin: числах, булевых значениях, символах, строках, массивах и беззнаковых целых числах.

  • IDE для разработки на Kotlin – см. список IDE с официальной поддержкой Kotlin и инструментов с поддержкой плагинов сообщества.

Новые статьи в журнале Kotlin Multiplatform

  • Разработка нативных и кроссплатформенных приложений: как выбрать? – ознакомьтесь с нашим обзором и преимуществами разработки кроссплатформенных приложений и нативного подхода.

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

Новые и обновленные учебные материалы

  • Начало работы с Kotlin Multiplatform Mobile – познакомьтесь с кроссплатформенной мобильной разработкой с помощью Kotlin и создайте приложение, работающее как на Android, так и на iOS.

  • Разработка полнофункционального веб-приложения с Kotlin Multiplatform – создайте приложение, используя Kotlin на всех уровнях, с серверной частью Kotlin/JVM и веб-клиентом Kotlin/JS.

  • Разработка веб-приложения с React и Kotlin/JS – создайте приложение для браузера, изучив DSL Kotlin и функции типичной программы React.

Изменения в документации выпуска

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

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

Установка Kotlin 1.7.20

IntelliJ IDEA 2021.3, 2022.1 и 2022.2 автоматически предлагают обновить плагин Kotlin до 1.7.20.

Для Android Studio Dolphin (213), Electric Eel (221) и Flamingo (222) плагин Kotlin 1.7.20 будет добавлен с будущими обновлениями Android Studio.

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

Руководство по совместимости для Kotlin 1.7.20

Хотя Kotlin 1.7.20 – это инкрементальный выпуск, нам всё же пришлось внести несовместимые изменения, чтобы ограничить распространение проблем, возникших в Kotlin 1.7.0.

Подробный список таких изменений см. в руководстве по совместимости для Kotlin 1.7.20.

Последнее изменение: 10 января 2023
Что нового в Kotlin 1.8.0 Что нового в Kotlin 1.7.0

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

Spec-Zone.ru

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