Kotlin
A concise multiplatform language developed by JetBrains
Публикации и ответы на комментарии в блогах JetBrains не выходят на русском языке с 2022 года.
Приносим извинения за неудобства.
Вышел Kotlin 1.4-RC
Итак, мы почти у цели! Мы рады представить Kotlin 1.4-RC — релиз-кандидат следующей крупной версии нашего языка программирования. Читайте дальше, чтобы узнать, что нового в Kotlin 1.4-RC, и обязательно попробуйте его новые возможности, прежде чем они будут официально выпущены в Kotlin 1.4.
Особая благодарность всем, кто опробовал предыдущие предварительные релизы (1.4-M1, 1.4-M2 и 1.4-M3), поделился своим мнением и помог нам сделать эту версию Kotlin еще лучше!
В данной публикации мы рассмотрим новую функциональность и важнейшие улучшения в версии Kotlin 1.4-RC:
- Усовершенствованная поддержка
*.gradle.kts
в IDE, в том числе ручная загрузка конфигураций скриптов и улучшенное информирование об ошибках. - Все исходные наборы теперь включают зависимость от стандартной библиотеки по умолчанию — как в мультиплатформенных, так и в одноплатформенных проектах.
- Упрощенное управление зависимостями CocoaPods.
- Улучшенные интеграции Kotlin/JS для npm-зависимостей, CSS и Dukat в Gradle, а также возможность использовать аннотацию
@JsExport
в стандартном бэкенде компилятора. - Превью-версия привязок для API Node.js.
Улучшенная поддержка *.gradle.kts в IDE
В Kotlin 1.3.70 мы значительно улучшили поддержку скриптов Gradle Kotlin DSL (файлов *.gradle.kts) в IDE и продолжили улучшать ее в Kotlin 1.4-RC. Вот что реализовано в новой версии:
Ручная загрузка конфигурации скриптов для повышенной производительности
Ранее, когда вы добавляли новый плагин в блоки buildscript
или plugins
файла build.gradle.kts
, новая конфигурация скрипта загружалась автоматически в фоновом режиме. После ее применения вы могли использовать помощь при написании кода в добавленном плагине.
Чтобы повысить производительность, мы удалили процедуру автоматического применения изменений в конфигурацию скрипта при вводе информации. В Gradle 6.0 или более поздних версиях изменения в конфигурации следует применять вручную — нажмите Load Gradle Changes или повторно импортируйте проект Gradle.
В предыдущих версиях Gradle требовалось вручную загружать конфигурацию скрипта, нажимая кнопку Load Configuration в редакторе.
С выходом Gradle 6.0+ мы добавили в IntelliJ IDEA 2020.1 еще одно действие — Load Script Configurations. Оно загружает изменения в конфигурации скриптов без обновления всего проекта. Это занимает значительно меньше времени, чем повторный импорт целого проекта.
Улучшенный механизм сообщения об ошибках
Ранее вы могли видеть ошибки Gradle Daemon (процесса, который выполняется в фоновом режиме и отвечает за все связанные с Gradle задачи и активности) только в отдельных файлах журнала. Теперь, если вы используете Gradle 6.0 (или более позднюю версию), Gradle Daemon непосредственно возвращает всю информацию об ошибках и отображает ее в окне Build. Это избавляет от лишних хлопот и экономит время.
Меньше дублированного кода в конфигурации проекта
Благодаря улучшениям в плагине Kotlin Gradle вы можете писать меньше кода в своих файлах сборки Gradle: одна из самых распространенных команд теперь применяется по умолчанию.
Стандартная библиотека стала зависимостью по умолчанию
В подавляющем большинстве проектов требуется стандартная библиотека Kotlin. Начиная с версии 1.4-RC вам больше не нужно вручную объявлять зависимость от stdlib
в каждом исходном наборе — она будет добавлена по умолчанию. Автоматически добавляемая версия стандартной библиотеки будет той же, что и версия плагина Kotlin Gradle, поскольку они используют одну и ту же систему нумерации версий.
Вот как до версии 1.4 выглядела типичная конфигурация мультиплатформенного проекта с целями Android, iOS и JavaScript:
Теперь вам вообще не нужно вручную объявлять зависимость от стандартной библиотеки, а с появлением поддержки иерархических проектов (анонсированной в 1.4-M2) указывать другие зависимости следует только один раз. Благодаря этому ваш файл сборки Gradle станет значительно более коротким и читаемым:
В платформенные исходные наборы и исходные наборы, выделенные бэкендом, будет добавлена соответствующая стандартная библиотека, а в остальные будет добавлена общая стандартная библиотека. Плагин Kotlin Gradle выберет подходящую стандартную библиотеку JVM в зависимости от параметра kotlinOptions.jvmTarget
.
Если вы объявите зависимость от стандартной библиотеки вручную (например, если вам нужна ее другая версия), плагин Kotlin Gradle не будет переопределять ее или добавлять вторую стандартную библиотеку. Если же вам вовсе не нужна стандартная библиотека, вы можете добавить специальный флаг в свойства Gradle:
Kotlin/Native
Упрощенное управление зависимостями CocoaPods
Раньше после интеграции с менеджером зависимостей CocoaPods вы были вынуждены выполнять сборку частей вашего проекта (относящихся к iOS, macOS, watchOS или tvOS) в Xcode — отдельно от остальных частей вашего мультиплатформенного проекта. Остальные части можно было собирать в IntelliJ IDEA.
Кроме того, при каждом добавлении зависимости от хранящейся в CocoaPods библиотеки Objective-C (библиотека Pod) вам приходилось переключаться из IntelliJ IDEA в Xcode, запускать задание pod install
, после чего запускать сборку Xcode там.
Теперь вы можете управлять зависимостями Pod прямо в IntelliJ IDEA, пользуясь преимуществами, которые предоставляет данная IDE, — например, подсветкой кода и его автодополнением. Вы также можете собирать весь проект Kotlin c помощью Gradle без необходимости переключаться на Xcode. Это означает, что переходить в Xcode придется только тогда, когда возникнет необходимость писать код Swift/Objective-C или запускать ваше приложение на симуляторе или устройстве.
Теперь вы также можете работать с библиотеками Pod, сохраненными локально.
В зависимости от своих потребностей вы можете добавлять зависимости между:
- Проектом Kotlin и библиотеками Pod из репозитория CocoaPods.
- Проектом Kotlin и библиотеками Pod, сохраненными локально.
- Kotlin Pod (проектом Kotlin, используемым в роли зависимости CocoaPods) и проектом Xcode с одной или несколькими целями.
Завершите создание исходной конфигурации и, при добавлении новых зависимостей в CocoaPods, просто повторно выполняйте импорт проекта в IntelliJ IDEA. Новая зависимость будет добавлена автоматически — других действий не требуется.
Ниже описывается, как добавить зависимости от библиотек Pod из репозитория CocoaPods. В документации Kotlin 1.4 охвачены все возможные сценарии.
Как пользоваться интеграцией c CocoaPods
Установите менеджер зависимостей CocoaPods и его плагин
- Установите менеджер зависимостей
cocoapods
(sudo gem install cocoapods
). - Установите плагин
cocoapods-generate
(sudo gem install cocoapods-generate
). - В файле вашего проекта
build.gradle(.kts)
подключите плагин CocoaPods с помощьюkotlin("native.cocoapods")
:
Добавьте зависимости от библиотек Pod из репозитория CocoaPods
-
Добавьте зависимости от библиотек Pod, которые вы хотите использовать из репозитория CocoaPods, с помощью команды
pod()
. Вы также можете добавлять зависимости в виде subspecs. -
Заново импортируйте проект. Чтобы использовать зависимости из кода Kotlin, импортируйте пакеты:
Вы можете ознакомиться с примером проекта, где демонстрируется, как добавлять зависимости от библиотек Pod, сохраненных как удаленно, в репозитории CocoPods, так и локально.
Выполняемая по умолчанию генерация релизных файлов .dSYM на целях Apple
В результате аварийного завершения работы приложения iOS и его последующей отладки иногда требуется обращаться к отчетам по аварийному завершению работы, а чтобы привести такие отчеты в читабельный вид, как правило, требуется выполнить их символизацию. Для символизации адресов в Kotlin требуется пакет .dSYM для кода Kotlin. Начиная с версии 1.4-M3 компилятор Kotlin/Native создает файлы .dSYM для релизных двоичных файлов на платформах Darwin по умолчанию. Отключить это поведение можно с помощью флага компилятора -Xadd-light-debug=disable
. На других платформах эта возможность отключена по умолчанию. Чтобы включить или выключить ее в Gradle, используйте следующий синтаксис:
Улучшения производительности
Мы продолжаем работать над оптимизацией общей производительности процесса разработки Kotlin/Native:
- В версии 1.3.70 мы представили два нововведения для повышения производительности компиляции Kotlin/Native: кэширование зависимостей проекта и запуск компилятора из Gradle Daemon. Благодаря вашим отзывам нам удалось исправить различные проблемы и повысить общую стабильность этих возможностей, и мы будем продолжать работу в этом направлении.
- Кроме того, мы внесли ряд улучшений в производительность среды выполнения. Общая производительность среды выполнения повышена благодаря оптимизации сборщика мусора. Это улучшение особенно заметно в проектах с большим количеством долгоживущих объектов. Коллекции
HashMap
иHashSet
теперь работают быстрее благодаря обходу ненужных операций упаковки.
Kotlin/JS
В Kotlin 1.4-RC мы сделали аннотацию @JsExport
совместимой со стандартным бэкендом компилятора. Мы также предоставляем более надежные и точные способы управления npm-зависимостями и интеграцией с Dukat в проектах Gradle, углубляем поддержку CSS и, помимо прочего, также предлагаем превью-версию интеграции с API Node.js.
Аннотация @JsExport
для стандартного бэкенда компилятора
В предыдущих предрелизных версиях Kotlin 1.4 мы представили аннотацию @JsExport
, которая используется для создания объявлений верхнего уровня, доступных из JavaScript и TypeScript при использовании нового IR-бэкенда компилятора. Начиная с версии Kotlin 1.4-M3 эту аннотацию можно использовать с текущим стандартным бэкендом компилятора. Аннотирование объявления верхнего уровня с помощью @JsExport
при использовании текущего стандартного бэкенда компилятора отключает обфускацию имен в этом объявлении. Наличие этой аннотации в обоих бэкендах компилятора позволяет вам переходить между ними, не внося изменений в логику экспорта объявлений верхнего уровня.
Изменения в управлении npm-зависимостями
Обязательное указание версий в объявлениях зависимостей
Объявление зависимостей от npm-пакетов без указания номера версии усложняет управление используемыми вами пакетами. Поэтому указание версии или диапазона версий зависимостей с помощью синтаксиса npm semver теперь стало обязательным. Gradle DSL теперь поддерживает указание нескольких диапазонов зависимостей, позволяя вам точно указать, какие версии вы хотите принимать в своем проекте, например:
Мы понимаем, что индивидуально менять эти настройки для каждого задания не очень удобно. Поэтому мы рассматриваем возможность добавления центральной точки конфигурирования cssSupport
в DSL плагина (отслеживать прогресс реализации этой функциональности можно здесь).
Улучшения в интеграции с Dukat
В Gradle-плагин Kotlin/JS добавлено более тонкое управление интеграцией плагина с Dukat — инструментом для автоматического преобразования файлов объявлений TypeScript (.d.ts
) во внешние объявления Kotlin. Теперь есть два способа выбрать ситуации, при которых Dukat генерирует зависимости:
Генерация внешних объявлений на этапе сборки
Функция npm-зависимости теперь принимает третий параметр (после наименования пакета и его версии): generateExternals
. Это позволяет вам в индивидуальном порядке контролировать, должен ли Dukat генерировать объявления для определенной зависимости. Пример:
Вы можете использовать флаг kotlin.js.generate.externals
(ранее, будучи экспериментальным, назывался kotlin.js.experimental.generateKotlinExternals
) в файле gradle.properties, чтобы установить поведение генератора для всех npm-зависимостей одновременно. Как обычно, индивидуальные вручную указанные параметры имеют приоритет над этим общим флагом.
Генерация внешних объявлений вручную с помощью задания Gradle
Если вам нужен полный контроль за объявлениями, которые генерирует Dukat, если хотите вручную применять корректировки или у вас возникают проблемы с автоматически генерируемыми внешними зависимостями, вы также можете инициировать создание объявлений для всех своих npm-зависимостей вручную с помощью задания Gradle generateExternals
. Оно сгенерирует объявления в директории externals
в корневой папке вашего проекта. Здесь вы можете просмотреть сгенерированный код и скопировать все части, которые вы хотите использовать в своих директориях исходников. Ручное размещение внешних объявлений в папке исходников и включение генерации внешних объявлений на этапе сборки для той же зависимости может вызвать проблемы с разрешением зависимостей.
Перенос kotlin.dom и kotlin.browser в отдельные артефакты
Чтобы ускорить эволюционирование наших привязок для DOM и браузера в Kotlin/JS, и сделать их независимыми от цикла релизов самого языка, мы прекращаем поддержку действующих API, размещенных в пакетах kotlin.dom
и kotlin.browser
. Заменой этим API будут служить пакеты kotlinx.dom
и kotlinx.browser
, которые будут извлечены в отдельные артефакты в предстоящем релизе. Миграция на новые API является очень простой и понятной. Просто поменяйте строки импорта, используемые в вашем проекте, чтобы они указывали на новые пакеты kotlinx.
Превью: kotlinx-nodejs
Мы очень рады поделиться с вами превью наших официальных привязок для API Node.js — kotlinx-nodejs
. Хотя таргетировать Node.js из Kotlin можно было уже давно, полный потенциал целевой платформы раскрывается при наличии типобезопасного доступа к ее API. Ознакомиться с привязками kotlinx-nodejs
можно на GitHub.
Чтобы добавить в проект kotlinx-nodejs
, добавьте jcenter()
в свой репозиторий. Затем вы можете просто добавить зависимость от артефакта:
После загрузки изменений Gradle вы можете поэкспериментировать с API, предоставляемым Node.js, например, воспользовавшись его пакетом разрешения DNS-имен:
Поскольку это превью-версия, приглашаем вас опробовать kotlinx-nodejs и сообщить о всех найденных ошибках в баг-трекер репозитория.
Прекращение поддержки Gradle-плагинов kotlin2js и kotlin-dce-js
Начиная с Kotlin 1.4 поддержка старых Gradle-плагинов для таргетирования JavaScript из Kotlin (kotlin2js
и kotlin-dce-js
) будет официально прекращена — используйте kotlin.js
. Ключевая функциональность, доступная в этих плагинах, вместе с плагином kotlin-frontend-plugin
(поддержка которого уже была прекращена ранее) объединена в новом плагине, что позволяет вам настраивать свою цель Kotlin/JS с помощью унифицированного DSL, также совместимого с мультиплатформенными проектами Kotlin.
Начиная с Kotlin 1.3.70 процедура удаления «мертвого» кода (DCE) применяется автоматически при использовании заданий browserProductionRun
и browserProductionWebpack
, создающих оптимизированные пакеты вашей программы. Обратите внимание, что устранение «мертвого» кода в настоящий момент доступно только при создании production-сборки для цели «браузер» (не работает с целью Node.js и тестовыми сборками). Однако, если имеются дополнительные сценарии использования, которые, на ваш взгляд, должны быть учтены, расскажите нам о них.
Дополнительные QoL-улучшения и важные исправления
- Мы расширили список ошибок компилятора ошибками для запрещенного применения аннотации
@JsExport
, чтобы привлекать внимание к подобным проблемам. - Реализована новая стратегия использования IR-бэкенда компилятора, включающая инкрементальную компиляцию файлов
klib
, что является одним из множества шагов, которые мы предпринимаем для уменьшения времени компиляции. - Скорректирована конфигурация сервера разработки webpack, чтобы предотвратить возникновение таких ошибок, как
ENOENT: no such file or directory
, при использовании функциональности «горячей перезагрузки» (hot reload).
Развитие API стандартной библиотеки Kotlin
В рамках эволюции Kotlin версия 1.4 является функциональным релизом, поэтому она содержит множество новых возможностей, с которыми вы уже знакомы по предыдущим публикациям. Однако еще одной важной отличительной чертой функционального релиза является внесение заметных эволюционных изменений в существующий API. Вот краткий обзор изменений, которые вас ожидают в версии 1.4.
Стабилизация экспериментального API
Чтобы как можно быстрее предоставлять новые возможности, которые вы желаете видеть в библиотеках Kotlin, мы выпускаем их экспериментальные версии. Экспериментальный статус сообщает о том, что работа над API еще не закончена и совместимость с будущими версиями не гарантируется. Если вы хотите воспользоваться экспериментальным API, компилятор предупреждает вас о его статусе и требует добавить аннотацию, подтверждающую согласие на использование этого API (@OptIn
).
В функциональных релизах экспериментальные API могут получать статус «стабильных». Это значит, что их форма и поведение не будут резко меняться (изменения возможны только с соблюдением надлежащего цикла прекращения поддержки). Как только API официально становится стабильным, вы можете спокойно использовать API без предупреждений и применения аннотации.
В версии 1.4 мы повышаем статус ряда экспериментальных функций в библиотеках Kotlin до «стабильного». Вот несколько примеров с указанием версий, в которых они были представлены:
- 1.3.40: функции преобразования между
CharArray
/ByteArray
иString
:ByteArray.decodeToString
иString.encodeToByteArray
CharArray.concatToString
иString.toCharArray
- 1.3.50: битовые операции
countOneBits()
,countLeadingZeroBits()
,countTrailingZeroBits()
,takeHighestOneBit()
,takeLowestOneBit()
- 1.3.70: операции с коллекциями
randomOrNull()
,reduceOrNull()
,scan()
; функцииremove*()
наMutableList
; классArrayDeque
- 1.4-M2: операции с коллекциями
onEachIndexed()
иreduceIndexedOrNull()
,runningFold()
иrunningReduce()
Все больше функций и классов API становятся стабильными в 1.4. Начиная с текущей версии (1.4-RC) их можно использовать без аннотации @OptIn
.
Циклы прекращения поддержки
В рамках функциональных релизов также выполняются следующие этапы ранее запущенных циклов прекращения поддержки. В инкрементальных релизах мы начинаем новые циклы прекращения поддержки на уровне WARNING
, а в функциональных релизах мы повышаем этот уровень до ERROR
. Соответственно, элементы API, которые уже имели уровень ERROR
, могут быть полностью скрыты от нового использования в коде и остаться только в двоичной форме с целью сохранения совместимости с ранее скомпилированным кодом. Подобный пошаговый процесс обеспечивает постепенное удаление отключаемых элементов API.
Если в вашем коде есть элементы API с уровнем прекращения поддержки WARNING
, компилятор предупреждает вас об этом. Когда вы обновитесь до Kotlin 1.4-RC, некоторые из этих предупреждений превратятся в ошибки. Используйте подсказки IDE, чтобы правильно заменять такой код на предложенные альтернативы и обеспечивать корректную компиляцию вашего кода.
Подробную информацию об изменениях в API стандартной библиотеки Kotlin, «ломающих» совместимость, можно найти в руководстве по совместимости Kotlin 1.4.
Скриптинг
Мы пропускали этот раздел в последних публикациях блога, однако не прекратили работать над скриптингом в Kotlin, чтобы в 1.4 сделать его более стабильным, быстрым и простым в использовании. В версии Release Candidate уже можно наблюдать повышенную производительность, а также эффект от внедрения многочисленных исправлений и функциональных улучшений.
Переименование артефактов
Во избежание путаницы в наименованиях артефактов мы переименовали kotlin-scripting-jsr223-embeddable
и kotlin-scripting-jvm-host-embeddable
— они стали kotlin-scripting-jsr223
и kotlin-scripting-jvm-host
(без -embeddable
). Эти артефакты зависят от артефакта kotlin-compiler-embeddable
, который «заслоняет» идущие в комплекте сторонние библиотеки во избежание конфликтов использования. В рамках этого переименования для артефактов скриптинга выбором по умолчанию становится kotlin-compiler-embeddable
(которое, как правило, безопаснее). Если по какой-либо причине вам потребуются артефакты, зависящие от незаслоненного kotlin-compiler
, используйте версии артефактов с суффиксом -unshaded
(например, kotlin-scripting-jsr223-unshaded
). Обратите внимание, что переименование влияет только на артефакты скриптинга, которые предназначаются для непосредственного использования; наименования других артефактов остаются неизменными.
Прекращена поддержка плагина CLion для IDE
Мы начали цикл прекращения поддержки плагина CLion для IDE. Изначально он предназначался для отладки исполняемых файлов Kotlin/Native. Теперь данная возможность доступна в IntelliJ IDEA Ultimate. После релиза 1.4 мы прекратим публикацию плагина CLion для IDE. Если это прекращение поддержки вызывает какие-либо проблемы, свяжитесь с нами. Мы приложим все усилия, чтобы помочь вам решить их.
Совместимость
Как и во всех крупных релизах, ранее анонсированные циклы прекращения поддержки некоторых возможностей завершаются в Kotlin 1.4. Все эти ситуации были тщательно рассмотрены языковым комитетом и перечислены в нашем руководстве по совместимости Kotlin 1.4. Вы также можете ознакомиться с подробностями этих изменений в YouTrack.
Примечания к версии Release Candidate
Теперь, когда версия Kotlin 1.4 достигла этапа «финальный релиз-кандидат», самое время заняться компиляцией и публикацией! В отличие от предыдущих предрелизных версий, двоичные файлы, созданные в Kotlin 1.4-RC, будут гарантированно совместимы с Kotlin 1.4.0.
Как попробовать новую функциональность
Как и всегда, вы можете попробовать Kotlin онлайн по адресу play.kotl.in.
Вы можете обновить плагин Kotlin до версии 1.4-RC в IntelliJ IDEA или Android Studio. Посмотрите, как это сделать.
Чтобы продолжать работу над проектами, которые были созданы до установки данной превью-версии, вам потребуется настроить свою сборку под превью-версию в Gradle или Maven. В отличие от предыдущих превью-версий, версия Kotlin 1.4-RC также доступна непосредственно на Maven Central. Это означает, что вам не нужно вручную добавлять репозиторий kotlin-eap
в свои файлы сборки.
Скачать компилятор для командной строки можно с GitHub-страницы релиза.
Вы можете использовать следующие версии библиотек, публикуемых с данным релизом:
- kotlinx.atomicfu: INSERT
- kotlinx.coroutines: INSERT
- kotlinx.serialization: INSERT
- ktor: INSERT
Подробные сведения о релизе и список совместимых библиотек также доступны здесь.
Что думаете?
Сообщайте нам об обнаруженных ошибках через баг-трекер — мы очень ценим вашу помощь. Все серьезные ошибки мы постараемся исправить до финального релиза, то есть вам не придется дожидаться следующего релиза Kotlin для устранения обнаруженных вами ошибок.
Также приглашаем вас подписаться на канал #eap в рабочем пространстве Kotlin в Slack (приглашение можно получить здесь). Там вы сможете задавать вопросы, участвовать в дискуссиях и получать уведомления о новых превью-сборках.
Let's Kotlin!
Внешние контрибьюторы
Мы очень благодарны всем внешним контрибьюторам, чьи пулреквесты были включены в этот релиз:
- Toshiaki Kameyama
- Steven Schäfer
- Jinseong Jeon
- pyos
- Mark Punzalan
- rapturemain
- Vitaly
- Mads Ager
- Subroh Nishikori
- Juan Chen
- gcx11
- rbares
- Henrik Tunedal
- Efeturi Money
- Yuku Kotani
- Дмитрий Бородин
- Михаил Лихолетов
- Mike Samuel
- Matthew Gharrity
- Jim Sproch
- Raluca Sauciuc
- Martin Petrov
- Segun Famisa
- Sinan Kozak
- Kristoffer Andersen
- Анастасия Краснорядцева
- Вадим Семенов
- Kevin Most
- Валерий Вырва
- Виктор Туранский