Что нового в Kotlin 1.8.0
Дата выпуска: 28 декабря 2022 года
Вышла версия Kotlin 1.8.0, и вот некоторые из ключевых нововведений:
Новые экспериментальные функции для JVM: рекурсивное копирование или удаление содержимого директории
Новый компиляторный параметр -Xdebug для улучшенного опыта отладки
kotlin-stdlib-jdk7иkotlin-stdlib-jdk8объединены вkotlin-stdlib
Поддержка IDE
Плагин Kotlin, поддерживающий 1.8.0, доступен для:
IDE |
Поддерживаемые версии |
|---|---|
IntelliJ IDEA |
2021.3, 2022.1, 2022.2 |
Android Studio |
Electric Eel (221), Flamingo (222) |
Kotlin/JVM
Начиная с версии 1.8.0, компилятор может генерировать классы с версией байткода, соответствующей JVM 19. Новая версия языка также включает:
Параметр компилятора для отключения генерации целей JVM аннотаций
Новый
-Xdebugпараметр компилятора для отключения оптимизаций
Возможность не генерировать цели аннотаций TYPE_USE и TYPE_PARAMETER
Если Kotlin аннотация имеет TYPE среди своих Kotlin целей, то аннотация отображается на java.lang.annotation.ElementType.TYPE_USE в списке целей Java аннотаций. Это аналогично тому, как TYPE_PARAMETER Kotlin цель отображается на java.lang.annotation.ElementType.TYPE_PARAMETER Java цель. Это проблема для Android клиентов с API уровнями меньше 26, у которых нет этих целей в API.
Начиная с Kotlin 1.8.0, вы можете использовать новый параметр компилятора -Xno-new-java-annotation-targets чтобы избежать генерации целей аннотаций TYPE_USE и TYPE_PARAMETER.
Новый компиляторный параметр для отключения оптимизаций
Kotlin 1.8.0 добавляет новый -Xdebug компиляторный параметр, который отключает оптимизации для лучшего опыта отладки. Пока что параметр отключает функцию «была оптимизирована» для корутин. В будущем, после добавления других оптимизаций, этот параметр также отключит их.
Функция «была оптимизирована» оптимизирует переменные при использовании suspend функций. Однако отладка кода с оптимизированными переменными затруднена, потому что вы не видите их значения.
Удаление старого бэкэнда
В Kotlin 1.5.0 мы объявили, что IR-бэкэнд стал стабильным. Это означало, что старый бэкэнд из Kotlin 1.4.* был устаревшим. В Kotlin 1.8.0 мы полностью удалили старый бэкэнд. Соответственно, мы удалили компиляторный параметр -Xuse-old-backend и параметр Gradle useOldBackend.
Поддержка аннотации Lombok @Builder
Сообщество добавило много голосов за запрос YouTrack Kotlin Lombok: Поддержка сгенерированных билдеров (@Builder), поэтому мы просто добавили поддержку @аннотации Builder.
Пока нет планов по поддержке @SuperBuilder или @Tolerate аннотаций, но мы пересмотрим этот вопрос, если за запросы @SuperBuilder и @Tolerate будет достаточно голосов.
Kotlin/Native
В Kotlin 1.8.0 внесены изменения в межплатформенную совместимость с Objective-C и Swift, добавлена поддержка Xcode 14.1, а также улучшен плагин CocoaPods Gradle:
Улучшенная межплатформенная совместимость с Objective-C/Swift
Динамические фреймворки по умолчанию в плагине CocoaPods Gradle
Поддержка Xcode 14.1
Компилятор Kotlin/Native теперь поддерживает последнюю стабильную версию Xcode, 14.1. Улучшения совместимости включают следующие изменения:
Добавлен новый
watchosDeviceArm64пресет для целевой платформы watchOS, который поддерживает Apple watchOS на платформах ARM64.Плагин Kotlin CocoaPods Gradle больше не включает встраивание bitcode для фреймворков Apple по умолчанию.
Библиотеки платформы были обновлены в соответствии с изменениями в Objective-C фреймворках для целей Apple.
Улучшенная межплатформенная совместимость с Objective-C/Swift
Для повышения совместимости Kotlin с Objective-C и Swift были добавлены три новые аннотации:
-
@ObjCNameпозволяет указать более удобочитаемое имя на Swift или Objective-C вместо переименования объявления Kotlin.Аннотация указывает компилятору Kotlin использовать пользовательское имя Objective-C и Swift для этого класса, свойства, параметра или функции:
@ObjCName(swiftName = "MySwiftArray") class MyKotlinArray { @ObjCName("index") fun indexOf(@ObjCName("of") element: String): Int = TODO() } // Usage with the ObjCName annotations let array = MySwiftArray() let index = array.index(of: "element") -
@HiddenFromObjCпозволяет скрыть объявление Kotlin от Objective-C.Аннотация указывает компилятору Kotlin не экспортировать функцию или свойство в Objective-C и, следовательно, в Swift. Это может сделать ваш код Kotlin более дружественным для Objective-C/Swift.
-
@ShouldRefineInSwiftполезна для замены объявления Kotlin на обертку, написанную на Swift.Аннотация указывает компилятору Kotlin отметить функцию или свойство как
swift_privateв сгенерированном API Objective-C. Такие объявления получают префикс__, делая их невидимыми для Swift-кода.Вы по-прежнему можете использовать эти объявления в коде Swift для создания дружественного к Swift API, но они не будут предлагаться автодополнением Xcode, например.
Дополнительную информацию об уточнении объявлений Objective-C в Swift см. в официальной документации Apple.
Команда Kotlin выражает огромную благодарность Рику Клефасу за реализацию этих аннотаций.
Динамические фреймворки по умолчанию в плагине CocoaPods Gradle
Начиная с Kotlin 1.8.0, Kotlin фреймворки, зарегистрированные плагином CocoaPods Gradle, по умолчанию подключаются динамически. Предыдущая статическая реализация была несовместима с поведением плагина Kotlin Gradle.
kotlin {
cocoapods {
framework {
baseName = "MyFramework"
isStatic = false // Now dynamic by default
}
}
}
Если у вас есть существующий проект со статическим типом подключения, и вы обновляетесь до Kotlin 1.8.0 (или явно меняете тип подключения), вы можете столкнуться с ошибкой при выполнении проекта. Для исправления закройте проект Xcode и выполните pod install в каталоге Podfile.
Дополнительную информацию см. в справке по языку DSL плагина CocoaPods Gradle.
Kotlin Multiplatform: Новая структура наборов исходных кодов Android
Kotlin 1.8.0 вводит новую структуру наборов исходных кодов Android, которая заменяет предыдущую схему именования директорий, которая была неоднозначной.
Рассмотрим пример двух androidTest директорий, созданных в текущей структуре. Одна предназначена для KotlinSourceSets, а другая — для AndroidSourceSets:
Они имеют разные семантики:
androidTestKotlin принадлежит типуunitTest, а Android — типуintegrationTest.Они создают запутанную
SourceDirectoriesструктуру, так какsrc/androidTest/javaимеетUnitTest, аsrc/androidTest/kotlinимеетInstrumentedTest.И
KotlinSourceSets, иAndroidSourceSetsиспользуют аналогичную схему именования для конфигураций Gradle, поэтому результирующие конфигурацииandroidTestдля наборов исходных кодов Kotlin и Android одинаковы:androidTestImplementation,androidTestApi,androidTestRuntimeOnly, иandroidTestCompileOnly.
Для решения этих и других проблем мы ввели новую структуру наборов исходных кодов Android. Вот основные отличия между двумя структурами:
Схема именования KotlinSourceSet
Текущая структура набора исходных кодов |
Новая структура набора исходных кодов |
|---|---|
|
|
{AndroidSourceSet.name} отображается на {KotlinSourceSet.name} следующим образом:
Текущая структура набора исходных кодов |
Новая структура набора исходных кодов |
|
|---|---|---|
main |
androidMain |
androidMain |
test |
androidTest |
androidUnitTest |
androidTest |
androidAndroidTest |
androidInstrumentedTest |
SourceDirectories
Текущая структура набора исходных кодов |
Новая структура набора исходных кодов |
|---|---|
Структура добавляет дополнительные |
|
{AndroidSourceSet.name} отображается на {SourceDirectories included} следующим образом:
Текущая структура набора исходных кодов |
Новая структура набора исходных кодов |
|
|---|---|---|
main |
src/androidMain/kotlin, src/main/kotlin, src/main/java |
src/androidMain/kotlin, src/main/kotlin, src/main/java |
test |
src/androidTest/kotlin, src/test/kotlin, src/test/java |
src/androidUnitTest/kotlin, src/test/kotlin, src/test/java |
androidTest |
src/androidAndroidTest/kotlin, src/androidTest/java |
src/androidInstrumentedTest/kotlin, src/androidTest/java, src/androidTest/kotlin |
Расположение файла AndroidManifest.xml
Текущая структура набора исходных кодов |
Новая структура набора исходных кодов |
|---|---|
src/{AndroidSourceSet.name}/AndroidManifest.xml |
src/{KotlinSourceSet.name}/AndroidManifest.xml |
{AndroidSourceSet.name} отображается на {AndroidManifest.xml location} следующим образом:
Текущая структура набора исходных кодов |
Новая структура набора исходных кодов |
|
|---|---|---|
main |
src/main/AndroidManifest.xml |
src/androidMain/AndroidManifest.xml |
debug |
src/debug/AndroidManifest.xml |
src/androidDebug/AndroidManifest.xml |
Конфигурация и настройка
Новая структура станет стандартной в будущих выпусках. Вы можете включить её сейчас с помощью следующего параметра Gradle:
kotlin.mpp.androidSourceSetLayoutVersion=2
Использование предыдущих директорий в стиле Android теперь не рекомендуется. Kotlin 1.8.0 знаменует начало процесса устаревания, выводя предупреждение о текущей структуре. Вы можете подавить предупреждение с помощью следующей свойства Gradle:
kotlin.mpp.androidSourceSetLayoutVersion1.nowarn=true
Kotlin/JS
Kotlin 1.8.0 стабилизирует компилятор бэкенд JS IR и добавляет новые возможности в скрипты сборки Gradle, связанные с JavaScript:
Стабильный бэкенд компилятора JS IR
Начиная с этого релиза, бэкенд компилятора Kotlin/JS промежуточного представления (IR-основанного) является стабильным. Потребовалось время для унификации инфраструктуры для всех трех бэкендов, но теперь они работают с тем же IR для кода Kotlin.
Вследствие стабильного бэкенда компилятора JS IR, предыдущий теперь устарел.
Инкрементная компиляция включена по умолчанию вместе со стабильным компилятором JS IR.
Если вы всё ещё используете старый компилятор, переключите свой проект на новый бэкенд с помощью нашего руководства по миграции.
Новые настройки для сообщения об обновлении yarn.lock
Если вы используете менеджер пакетов yarn, есть три новых специальных настройки Gradle, которые могут уведомлять вас, если файл yarn.lock был обновлён. Вы можете использовать эти настройки, когда хотите быть уведомлёнными, если yarn.lock был изменён незаметно во время процесса сборки CI.
Эти три новых свойства Gradle:
-
YarnLockMismatchReport, которое определяет, как сообщения об изменениях в файлеyarn.lockвыводятся. Вы можете использовать одно из следующих значений:FAILприводит к провалу соответствующей задачи Gradle. Это значение по умолчанию.WARNINGзаписывает информацию об изменениях в журнале предупреждений.NONEотключает сообщения.
reportNewYarnLock, которое явно сообщает об недавно созданном файлеyarn.lock. По умолчанию этот параметр отключён: обычно новый файлyarn.lockгенерируется при первом запуске. Вы можете использовать этот параметр, чтобы убедиться, что файл добавлен в ваш репозиторий.yarnLockAutoReplace, который автоматически заменяетyarn.lockкаждый раз, когда запускается задача Gradle.
Чтобы использовать эти параметры, обновите свой файл скрипта сборки build.gradle.kts следующим образом:
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin::class.java) {
rootProject.the<YarnRootExtension>().yarnLockMismatchReport =
YarnLockMismatchReport.WARNING // NONE | FAIL
rootProject.the<YarnRootExtension>().reportNewYarnLock = false // true
rootProject.the<YarnRootExtension>().yarnLockAutoReplace = false // true
}
Добавление целей тестирования для браузеров через свойства Gradle
Начиная с Kotlin 1.8.0, вы можете задавать цели тестирования для разных браузеров прямо в файле свойств Gradle. Это сокращает размер файла скрипта сборки, поскольку вам больше не нужно писать все цели в build.gradle.kts.
Вы можете использовать это свойство для определения списка браузеров для всех модулей, а затем добавить конкретные браузеры в скриптах сборки отдельных модулей.
Например, следующая строка в вашем файле свойств Gradle запустит тесты в Firefox и Safari для всех модулей:
kotlin.js.browser.karma.browsers=firefox,safari
См. полный список доступных значений для свойства на GitHub.
Команда Kotlin выражает огромную благодарность Martynas Petuška за реализацию этой функции.
Новый подход к добавлению поддержки CSS в ваш проект
В этом релизе представлен новый подход к добавлению поддержки CSS в ваш проект. Мы предполагаем, что это затронет множество проектов, поэтому не забудьте обновить ваши файлы скриптов сборки Gradle, как описано ниже.
Перед Kotlin 1.8.0, для добавления поддержки CSS использовалось свойство cssSupport.enabled.
cssSupport.enabled = true
Теперь вы должны использовать метод enabled.set() в блоке cssSupport{}.
cssSupport {
enabled.set(true)
}
Gradle
Kotlin 1.8.0 полностью поддерживает версии Gradle 7.2 и 7.3. Вы также можете использовать версии Gradle до последней версии выпуска, но если вы это делаете, имейте в виду, что могут появиться предупреждения об устаревании или некоторые новые функции Gradle могут не работать.
Эта версия принесла множество изменений:
Предоставление параметров компилятора Kotlin в качестве ленивых свойств Gradle
Возможность отключить стратегию резервного копирования демона Kotlin
Использование последней версии kotlin-stdlib в транзитивных зависимостях
Обязательная проверка совместимости целевых JVM задач компиляции Kotlin и Java
Предоставление параметров компилятора Kotlin в качестве ленивых свойств Gradle
Для предоставления доступных параметров компилятора Kotlin в качестве ленивых свойств Gradle и для лучшей интеграции их в задачи Kotlin, мы внесли много изменений:
-
Задачи компиляции имеют новый
compilerOptionsввод, аналогичный существующемуkotlinOptions, но использующийPropertyиз API свойств Gradle в качестве возвращаемого типа:tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile::class.java) { compilerOptions { useK2.set(true) } } Задачи Kotlin-инструментов
KotlinJsDceиKotlinNativeLinkимеют новыйtoolOptionsвход, аналогичный существующемуkotlinOptionsвходу.Новые входы имеют аннотацию
@NestedGradle. Каждое свойство внутри входов имеет связанную аннотацию Gradle, такую как@Inputили@Internal.-
API артефакт плагина Kotlin Gradle имеет два новых интерфейса:
org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask, который имеетcompilerOptionsвход иcompileOptions()метод. Все задачи компиляции Kotlin реализуют этот интерфейс.org.jetbrains.kotlin.gradle.tasks.KotlinToolTask, который имеетtoolOptionsвход иtoolOptions()метод. Все инструменты Kotlin –KotlinJsDce,KotlinNativeLink, иKotlinNativeLinkArtifactTask– реализуют этот интерфейс.
-
Некоторые
compilerOptionsиспользуют новые типы вместо типаString:KotlinVersion(для входовapiVersionиlanguageVersion)
Например, вы можете использовать
compilerOptions.jvmTarget.set(JvmTarget.JVM_11)вместоkotlinOptions.jvmTarget = "11".Типы
kotlinOptionsне изменились и неявно преобразуются в типыcompilerOptions. API плагина Kotlin Gradle бинарно совместим с предыдущими выпусками. Однако, в артефакте
kotlin-gradle-pluginесть некоторые изменения, нарушающие структуру исходного кода и ABI. Большинство этих изменений связаны с добавлением дополнительных обобщенных параметров к некоторым внутренним типам. Важное изменение заключается в том, что задачаKotlinNativeLinkбольше не наследует задачуAbstractKotlinNativeCompile.KotlinJsCompilerOptions.outputFileи связанные с ним опцииKotlinJsOptions.outputFileустарели. Используйте вход задачиKotlin2JsCompile.outputFilePropertyвместо этого.
Ограничения
Вызов любого метода set или get для kotlinOptions делегирует вызов соответствующему свойству в compilerOptions . Это приводит к следующим ограничениям:
compilerOptionsиkotlinOptionsнельзя изменить на стадии выполнения задачи (есть одно исключение в абзаце ниже).freeCompilerArgsвозвращает неизменяемыйList<String>, что означает, что, например,kotlinOptions.freeCompilerArgs.remove("something")потерпит неудачу.
Некоторые плагины, включая kotlin-dsl и плагин Android Gradle (AGP) с включенным Jetpack Compose, пытаются изменить атрибут freeCompilerArgs в фазе выполнения задачи. Мы добавили обходной путь для них в Kotlin 1.8.0. Этот обходной путь позволяет любому скрипту сборки или плагину изменять kotlinOptions.freeCompilerArgs в фазе выполнения, но генерирует предупреждение в журнале сборки. Чтобы отключить это предупреждение, используйте новое свойство Gradle kotlin.options.suppressFreeCompilerArgsModificationWarning=true. Gradle добавит исправления для kotlin-dsl плагина и AGP с включенным Jetpack Compose.
Повышение минимальных поддерживаемых версий
Начиная с Kotlin 1.8.0, минимальная поддерживаемая версия Gradle — 6.8.3, а минимальная поддерживаемая версия плагина Android Gradle — 4.1.3.
См. совместимость плагина Kotlin Gradle с доступными версиями Gradle в нашей документации
Возможность отключить стратегию резервного копирования демона Kotlin
Существует новое свойство Gradle kotlin.daemon.useFallbackStrategy, значение которого по умолчанию true. Когда значение равно false, сборка завершается с ошибкой при проблемах с запуском или взаимодействием демона. Также есть новое свойство useDaemonFallbackStrategy в задачах компиляции Kotlin, которое имеет приоритет над свойством Gradle, если вы используете их оба. Если памяти недостаточно для выполнения компиляции, в логах будет соответствующее сообщение.
Стратегия резервного копирования компилятора Kotlin — запуск компиляции вне демона Kotlin, если по какой-то причине демон не работает. Если деamon Gradle включен, компилятор использует стратегию "В процессе". Если Gradle daemon выключен, компилятор использует стратегию "Вне процесса". Узнайте больше о этих стратегиях выполнения в документации. Обратите внимание, что пассивное переключение на другую стратегию может потреблять большое количество системных ресурсов или привести к непредсказуемым результатам сборки; см. эту задачу YouTrack для получения более подробной информации.
Использование последней версии kotlin-stdlib в зависимостях
Если вы явно указываете версию Kotlin 1.8.0 или выше в своих зависимостях, например: implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.0"), тогда плагин Kotlin Gradle будет использовать эту версию Kotlin для транзитивных kotlin-stdlib-jdk7 и kotlin-stdlib-jdk8 зависимостей. Это делается для предотвращения дублирования классов из разных версий stdlib (подробнее о слиянии kotlin-stdlib-jdk7 и kotlin-stdlib-jdk8 в kotlin-stdlib). Вы можете отключить это поведение с помощью свойства Gradle kotlin.stdlib.jdk.variants.version.alignment.
kotlin.stdlib.jdk.variants.version.alignment=false
Если у вас возникнут проблемы с согласованием версий, согласуйте все версии через Kotlin BOM, объявив платформную зависимость от kotlin-bom в вашем скрипте сборки:
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
Узнайте о других случаях и наших рекомендуемых решениях в документации.
Обязательная проверка целевых JVM для связанных задач компиляции Kotlin и Java
Начиная с этого выпуска, значение по умолчанию для свойства kotlin.jvm.target.validation.mode равно error для проектов на Gradle 8.0+ (эта версия Gradle еще не выпущена), и плагин завершит сборку в случае несовместимости целевых JVM.
Переход значения по умолчанию от warning к error — это подготовительный шаг для плавной миграции на Gradle 8.0. Рекомендуем установить это свойство в значение error и настроить инструмент или вручную согласовать версии JVM.
Узнайте больше о том, что может пойти не так, если не проверить совместимость целей.
Разрешение транзитивных зависимостей плагинов Kotlin Gradle
В Kotlin 1.7.0 мы представили поддержку вариантов плагинов Gradle. Из-за этих вариантов плагинов, класс пути сборки может содержать разные версии плагинов Kotlin Gradle, которые зависят от различных версий некоторой зависимости, обычно kotlin-gradle-plugin-api. Это может привести к проблеме разрешения, и мы хотим предложить следующее решение, используя плагин kotlin-dsl в качестве примера.
Плагин kotlin-dsl в Gradle 7.6 зависит от плагина org.jetbrains.kotlin.plugin.sam.with.receiver:1.7.10, который зависит от kotlin-gradle-plugin-api:1.7.10. Если вы добавите плагин org.jetbrains.kotlin.gradle.jvm:1.8.0, эта транзитивная зависимость kotlin-gradle-plugin-api:1.7.10 может привести к ошибке разрешения зависимостей из-за несоответствия версий (1.8.0 и 1.7.10) и значений атрибутов варианта org.gradle.plugin.api-version. В качестве решения добавьте это ограничение ограничение для согласования версий. Это решение может потребоваться до внедрения платформы выравнивания библиотек плагинов Kotlin Gradle, что запланировано.
dependencies {
constraints {
implementation("org.jetbrains.kotlin:kotlin-sam-with-receiver:1.8.0")
}
}
Это ограничение заставляет использовать версию org.jetbrains.kotlin:kotlin-sam-with-receiver:1.8.0 в пути класса сборки для транзитивных зависимостей. Подробнее об одном похожем случае вы можете узнать в трекере задач Gradle.
Устаревшие и удалённые элементы
В Kotlin 1.8.0 продолжается цикл устаревания следующих свойств и методов:
В заметках к Kotlin 1.7.0 упоминалось, что задача
KotlinCompileвсё ещё содержала устаревшее свойство Kotlinclasspath, которое будет удалено в будущих выпусках. Сейчас мы изменили уровень устаревания наerrorдля свойстваKotlinCompileзадачиclasspath. Все задачи компиляции используют входlibrariesдля списка библиотек, необходимых для компиляции.Мы удалили свойство
kapt.use.worker.api, которое позволяло запускать kapt через API Gradle Workers. По умолчанию kapt использует рабочие процессы Gradle с Kotlin 1.3.70, и мы рекомендуем придерживаться этого метода.В Kotlin 1.7.0 мы объявили о начале цикла устаревания свойства
kotlin.compiler.execution.strategy. В этом релизе мы удалили это свойство. Узнайте, как определять стратегию выполнения компилятора Kotlin другими способами.
Стандартная библиотека
Kotlin 1.8.0:
Обновления целевой версии JVM для компиляции.
Стабилизированы ряд функций – преобразование единиц времени между Java и Kotlin,
cbrt(), JavaOptionalsрасширяющие функции.Предоставлен предварительный просмотр сравнимых и вычитаемых
TimeMarks.Включает экспериментальные расширяющие функции для
java.nio.file.path.Представлена улучшенная производительность kotlin-reflect.
Обновлённая целевая версия JVM для компиляции
В Kotlin 1.8.0 стандартные библиотеки (kotlin-stdlib, kotlin-reflect, и kotlin-script-*) скомпилированы с целевой версией JVM 1.8. Ранее стандартные библиотеки компилировались с целевой версией JVM 1.6.
Kotlin 1.8.0 больше не поддерживает целевые версии JVM 1.6 и 1.7. В результате, вам больше не нужно объявлять kotlin-stdlib-jdk7 и kotlin-stdlib-jdk8 отдельно в скриптах сборки, так как содержимое этих артефактов объединено в kotlin-stdlib.
Обратите внимание, что смешивание разных версий артефактов stdlib может привести к дублированию классов или отсутствию необходимых. Для предотвращения этого плагин Kotlin Gradle поможет вам выровнять версии stdlib.
cbrt()
Функция cbrt(), позволяющая вычислить действительный кубический корень из double или float, теперь стабильна.
import kotlin.math.*
fun main() {
val num = 27
val negNum = -num
println("The cube root of ${num.toDouble()} is: " +
cbrt(num.toDouble()))
println("The cube root of ${negNum.toDouble()} is: " +
cbrt(negNum.toDouble()))
}
Преобразование единиц времени между Java и Kotlin
Функции toTimeUnit() и toDurationUnit() в kotlin.time теперь стабильны. Введённые как экспериментальные в Kotlin 1.6.0, эти функции улучшают межплатформенную совместимость Kotlin и Java. Теперь вы можете легко преобразовывать между Java java.util.concurrent.TimeUnit и Kotlin kotlin.time.DurationUnit. Эти функции поддерживаются только на JVM.
import kotlin.time.*
// For use from Java
fun wait(timeout: Long, unit: TimeUnit) {
val duration: Duration = timeout.toDuration(unit.toDurationUnit())
...
}
Сравнимые и вычитаемые отметки времени
До Kotlin 1.8.0, если вы хотели вычислить разницу во времени между несколькими TimeMarks и текущим моментом, вы могли вызывать elapsedNow() только для одной TimeMark за раз. Это затрудняло сравнение результатов, так как два вызова функции elapsedNow() не могли быть выполнены точно в одно и то же время.
Для решения этой проблемы, в Kotlin 1.8.0 вы можете вычитать и сравнивать TimeMarks из одного и того же источника времени. Теперь вы можете создать новый экземпляр TimeMark для представления текущего момента и вычитать другие TimeMarks из него. Таким образом, результаты, которые вы получаете от этих вычислений, гарантированно будут относительны друг к другу.
import kotlin.time.*
fun main() {
//sampleStart
val timeSource = TimeSource.Monotonic
val mark1 = timeSource.markNow()
Thread.sleep(500) // Sleep 0.5 seconds
val mark2 = timeSource.markNow()
// Before 1.8.0
repeat(4) { n ->
val elapsed1 = mark1.elapsedNow()
val elapsed2 = mark2.elapsedNow()
// Difference between elapsed1 and elapsed2 can vary depending
// on how much time passes between the two elapsedNow() calls
println("Measurement 1.${n + 1}: elapsed1=$elapsed1, " +
"elapsed2=$elapsed2, diff=${elapsed1 - elapsed2}")
}
println()
// Since 1.8.0
repeat(4) { n ->
val mark3 = timeSource.markNow()
val elapsed1 = mark3 - mark1
val elapsed2 = mark3 - mark2
// Now the elapsed times are calculated relative to mark3,
// which is a fixed value
println("Measurement 2.${n + 1}: elapsed1=$elapsed1, " +
"elapsed2=$elapsed2, diff=${elapsed1 - elapsed2}")
}
// It's also possible to compare time marks with each other
// This is true, as mark2 was captured later than mark1
println(mark2 > mark1)
//sampleEnd
}
Эта новая функциональность особенно полезна при расчётах анимации, когда вам нужно вычислить разницу между или сравнить несколько TimeMarks, представляющих разные кадры.
Рекурсивное копирование или удаление каталогов
Мы представили две новые расширяющие функции для java.nio.file.Path, copyToRecursively() и deleteRecursively(), которые позволяют вам рекурсивно:
Копировать каталог и его содержимое в другое место назначения.
Удалить каталог и его содержимое.
Эти функции могут быть очень полезными в процессе резервного копирования.
Обработка ошибок
Используя copyToRecursively(), вы можете определить, что должно произойти при возникновении исключения во время копирования, перегрузив лямбда-функцию onError.
sourceRoot.copyToRecursively(destinationRoot, followLinks = false,
onError = { source, target, exception ->
logger.logError(exception, "Failed to copy $source to $target")
OnErrorResult.TERMINATE
})
При использовании deleteRecursively(), если во время удаления файла или папки возникает исключение, то файл или папка пропускаются. После завершения удаления deleteRecursively() бросает исключение IOException с содержащимися в качестве подавленных исключениями.
Замена файла
Если copyToRecursively() обнаружит, что файл уже существует в каталоге назначения, возникает исключение. Если вы хотите перезаписать файл, используйте перегрузку, которая имеет overwrite в качестве аргумента и установите его в значение true.
fun setUpEnvironment(projectDirectory: Path, fixtureName: String) {
fixturesRoot.resolve(COMMON_FIXTURE_NAME)
.copyToRecursively(projectDirectory, followLinks = false)
fixturesRoot.resolve(fixtureName)
.copyToRecursively(projectDirectory, followLinks = false,
overwrite = true) // patches the common fixture
}
Настройка процесса копирования
Чтобы определить собственную логику копирования, используйте перегрузку, которая имеет copyAction в качестве дополнительного аргумента. Используя copyAction, вы можете предоставить лямбда-функцию, например, со своими действиями:
sourceRoot.copyToRecursively(destinationRoot, followLinks = false) { source, target ->
if (source.name.startsWith(".")) {
CopyActionResult.SKIP_SUBTREE
} else {
source.copyToIgnoringExistingDirectory(target, followLinks = false)
CopyActionResult.CONTINUE
}
}
Для получения дополнительной информации об этих расширяющих функциях, см. нашу справку по API.
Расширяющие функции для Java Optional
Расширяющие функции, введённые в Kotlin 1.7.0, теперь стабильны. Эти функции упрощают работу с классами Optional в Java. Они могут быть использованы для разворачивания и преобразования Optional объектов на JVM и для повышения лаконичности при работе с Java API. Для получения дополнительной информации, см. Что нового в Kotlin 1.7.0.
Улучшенная производительность kotlin-reflect
Используя тот факт, что kotlin-reflect теперь компилируется с целевой версией JVM 1.8, мы мигрировали нашу внутреннюю механизм кэширования на Java ClassValue. Раньше мы кэшировали только KClass, но теперь также кэшируем KType и KDeclarationContainer. Эти изменения привели к значительному улучшению производительности при вызове typeOf().
Обновления документации
Переработанные и новые страницы
Обзор Gradle – узнайте, как настроить и собрать проект Kotlin с помощью системы сборки Gradle, доступные опции компилятора, компиляция и кэширование в плагине Kotlin Gradle.
Обязательность в Java и Kotlin – ознакомьтесь с различиями между подходами Java и Kotlin к обработке потенциально нулевых переменных.
Руководство по Lincheck – узнайте, как настроить и использовать фреймворк Lincheck для тестирования конкурирующих алгоритмов на JVM.
Новые и обновлённые учебные пособия
Начало работы с Gradle и Kotlin/JVM – создание консольного приложения с использованием IntelliJ IDEA и Gradle.
Создание многоплатформенного приложения с помощью Ktor и SQLDelight – создание мобильного приложения для iOS и Android с использованием Kotlin Multiplatform Mobile.
Начало работы с Kotlin Multiplatform Mobile – ознакомьтесь с кроссплатформенной мобильной разработкой с помощью Kotlin и создайте приложение, работающее как на Android, так и на iOS.
Установка Kotlin 1.8.0
IntelliJ IDEA 2021.3, 2022.1 и 2022.2 автоматически предлагают обновить плагин Kotlin до версии 1.8.0. IntelliJ IDEA 2022.3 будет иметь версию плагина Kotlin 1.8.0, включённую в предстоящее обновление.
Для Android Studio Electric Eel (221) и Flamingo (222) версия 1.8.0 плагина Kotlin будет доставлена с предстоящими обновлениями Android Studio. Новый компилятор командной строки доступен для скачивания на странице выпуска GitHub.
Руководство по совместимости для Kotlin 1.8.0
Kotlin 1.8.0 является релизом новых функций и, следовательно, может привносить изменения, которые несовместимы с вашим кодом, написанным для более ранних версий языка. Подробный список этих изменений можно найти в Руководстве по совместимости для Kotlin 1.8.0.
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew18.html