Что нового в Kotlin 1.6.0
В Kotlin 1.6.0 появились новые возможности языка, оптимизации и улучшения существующих возможностей, а также множество улучшений стандартной библиотеки Kotlin.
Обзор изменений также представлен в публикации о выпуске.
Язык
В Kotlin 1.6.0 стабилизированы несколько возможностей языка, представленных в предыдущем выпуске 1.5.30 в предварительном режиме:
Стабильные исчерпывающие операторы when для субъектов типа enum, sealed и Boolean
Стабильные приостанавливающие функции в качестве суперклассов
Кроме того, в выпуске появились различные улучшения вывода типов и поддержка аннотаций параметров типов класса:
Стабильные исчерпывающие операторы when для субъектов типа enum, sealed и Boolean
Исчерпывающий when содержит ветви для всех возможных типов или значений своего субъекта либо для некоторых типов и ветвь else. Он охватывает все возможные варианты, делая код безопаснее.
В ближайшее время мы запретим неисчерпывающие операторы when, чтобы их поведение соответствовало поведению выражений when. Для обеспечения плавного перехода в Kotlin 1.6.0 выводятся предупреждения о неисчерпывающих операторах when с субъектами типа enum, sealed или Boolean. В будущих выпусках эти предупреждения станут ошибками.
sealed class Contact {
data class PhoneCall(val number: String) : Contact()
data class TextMessage(val number: String) : Contact()
}
fun Contact.messageCost(): Int =
when(this) { // Error: 'when' expression must be exhaustive
is Contact.PhoneCall -> 42
}
fun sendMessage(contact: Contact, message: String) {
// Starting with 1.6.0
// Warning: Non exhaustive 'when' statements on Boolean will be
// prohibited in 1.7, add 'false' branch or 'else' branch instead
when(message.isEmpty()) {
true -> return
}
// Warning: Non exhaustive 'when' statements on sealed class/interface will be
// prohibited in 1.7, add 'is TextMessage' branch or 'else' branch instead
when(contact) {
is Contact.PhoneCall -> TODO()
}
}
Более подробное объяснение изменения и его последствий см. в этой задаче YouTrack.
Стабильные приостанавливающие функции в качестве суперклассов
В Kotlin 1.6.0 реализация приостанавливающих функциональных типов получила статус Stable. Предварительная версия была доступна в версии 1.5.30.
Эта возможность может быть полезна при разработке API, использующих корутины Kotlin и принимающих приостанавливающие функциональные типы. Теперь код можно упростить, поместив нужное поведение в отдельный класс, реализующий приостанавливающий функциональный тип.
class MyClickAction : suspend () -> Unit {
override suspend fun invoke() { TODO() }
}
fun launchOnClick(action: suspend () -> Unit) {}
Экземпляр этого класса можно использовать там, где ранее допускались только лямбды и ссылки на приостанавливающие функции: launchOnClick(MyClickAction()).
В настоящее время есть два ограничения, обусловленных особенностями реализации:
Нельзя смешивать обычные и приостанавливающие функциональные типы в списке суперклассов.
Нельзя использовать несколько приостанавливающих функциональных суперклассов.
Стабильные преобразования в suspend-функции
В Kotlin 1.6.0 представлены стабильные преобразования обычных функциональных типов в приостанавливающие. Начиная с версии 1.4.0, эта возможность поддерживала функциональные литералы и ссылки на вызываемые объекты. В версии 1.6.0 она работает с выражениями любых видов. Теперь в качестве аргумента вызова можно передать любое выражение подходящего обычного функционального типа, если ожидается приостанавливающий тип. Компилятор автоматически выполнит неявное преобразование.
fun getSuspending(suspending: suspend () -> Unit) {}
fun suspending() {}
fun test(regular: () -> Unit) {
getSuspending { } // OK
getSuspending(::suspending) // OK
getSuspending(regular) // OK
}
Стабильное создание экземпляров классов аннотаций
В Kotlin 1.5.30 была добавлена экспериментальная поддержка создания экземпляров классов аннотаций на платформе JVM. В версии 1.6.0 эта возможность по умолчанию доступна для Kotlin/JVM и Kotlin/JS.
Подробнее о создании экземпляров классов аннотаций читайте в этом KEEP.
Улучшенный вывод типов для рекурсивных обобщённых типов
В Kotlin 1.5.30 было улучшено выведение типов для рекурсивных обобщённых типов: теперь аргументы типов можно выводить только на основе верхних границ соответствующих параметров типов. Это улучшение было доступно с помощью параметра компилятора. В версии 1.6.0 и последующих версиях оно включено по умолчанию.
// Before 1.5.30
val containerA = PostgreSQLContainer<Nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
withDatabaseName("db")
withUsername("user")
withPassword("password")
withInitScript("sql/schema.sql")
}
// With compiler option in 1.5.30 or by default starting with 1.6.0
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
.withDatabaseName("db")
.withUsername("user")
.withPassword("password")
.withInitScript("sql/schema.sql")
Изменения в выводе типов для построителей
Вывод типов для построителей — это разновидность вывода типов, полезная при вызове обобщённых функций-построителей. Она позволяет вывести аргументы типов вызова, используя информацию о типах из вызовов внутри лямбда-аргумента.
Мы вносим ряд изменений, приближающих нас к полной стабилизации вывода типов для построителей. Начиная с версии 1.6.0:
Внутри лямбды построителя можно вызывать функции, возвращающие экземпляр ещё не выведенного типа, не указывая параметр компилятора
-Xunrestricted-builder-inference, добавленный в версии 1.5.30.-
С помощью
-Xenable-builder-inferenceможно создавать собственные построители без аннотации@BuilderInference. С помощью
-Xenable-builder-inferenceвывод типов для построителей автоматически активируется, если обычному выводу типов недостаточно информации о типе.
Поддержка аннотаций параметров типов класса
Поддержка аннотаций параметров типов класса выглядит так:
@Target(AnnotationTarget.TYPE_PARAMETER)
annotation class BoxContent
class Box<@BoxContent T> {}
Аннотации всех параметров типов записываются в байт-код JVM, чтобы их могли использовать обработчики аннотаций.
Описание сценария использования, послужившего мотивацией для этой возможности, см. в этой задаче YouTrack.
Подробнее об аннотациях.
Более длительная поддержка предыдущих версий API
Начиная с Kotlin 1.6.0, мы будем поддерживать разработку для трёх предыдущих версий API вместо двух, наряду с текущей стабильной версией. В настоящее время поддерживаются версии 1.3, 1.4, 1.5 и 1.6.
Kotlin/JVM
Начиная с версии 1.6.0, компилятор Kotlin/JVM может создавать классы с версией байт-кода, соответствующей JVM 17. В новой версии языка также появились оптимизации делегированных свойств и повторяющиеся аннотации, которые были в нашей дорожной карте:
Повторяющиеся аннотации с хранением во время выполнения для целевой платформы JVM 1.8
Оптимизация делегированных свойств, вызывающих get/set для заданного экземпляра KProperty
Повторяющиеся аннотации с хранением во время выполнения для целевой платформы JVM 1.8
В Java 8 появились повторяющиеся аннотации, которые можно несколько раз применять к одному элементу кода. Для этой возможности в коде Java должны быть объявлены две сущности: сама повторяющаяся аннотация, помеченная @java.lang.annotation.Repeatable, и содержащая аннотация для хранения её значений.
В Kotlin также есть повторяющиеся аннотации, но для того, чтобы аннотация стала повторяющейся, в её объявлении достаточно указать только @kotlin.annotation.Repeatable. До версии 1.6.0 эта возможность поддерживала только хранение SOURCE и была несовместима с повторяющимися аннотациями Java. В Kotlin 1.6.0 эти ограничения сняты. Теперь @kotlin.annotation.Repeatable поддерживает любой тип хранения и делает аннотацию повторяющейся как в Kotlin, так и в Java. Повторяющиеся аннотации Java теперь также поддерживаются со стороны Kotlin.
Содержащую аннотацию можно объявить, но это необязательно. Например:
-
Если аннотация
@Tagпомечена@kotlin.annotation.Repeatable, компилятор Kotlin автоматически создаёт содержащий класс аннотации с именем@Tag.Container:@Repeatable annotation class Tag(val name: String) // The compiler generates @Tag.Container containing annotation
-
Чтобы задать собственное имя содержащей аннотации, примените метааннотацию
@kotlin.jvm.JvmRepeatableи передайте явно объявленный содержащий класс аннотации в качестве аргумента:@JvmRepeatable(Tags::class) annotation class Tag(val name: String) annotation class Tags(val value: Array<Tag>)
В Kotlin Reflection теперь поддерживаются повторяющиеся аннотации как Kotlin, так и Java благодаря новой функции KAnnotatedElement.findAnnotations().
Подробнее о повторяющихся аннотациях Kotlin читайте в этом KEEP.
Оптимизация делегированных свойств, вызывающих get/set для заданного экземпляра KProperty
Мы оптимизировали сгенерированный байт-код JVM: теперь поле $delegate опускается, а доступ к свойству осуществляется напрямую.
Например, в следующем коде
class Box<T> {
private var impl: T = ...
var content: T by ::impl
}
Kotlin больше не генерирует поле content$delegate. Методы доступа к свойству переменной content напрямую обращаются к переменной impl, пропуская операторы getValue/setValue делегированного свойства и тем самым устраняя необходимость в объекте ссылки на свойство типа KProperty.
Благодарим наших коллег из Google за реализацию!
Подробнее о делегированных свойствах.
Kotlin/Native
В Kotlin/Native появились многочисленные улучшения и обновления компонентов, некоторые из них доступны в предварительной версии:
Предварительная версия нового менеджера памяти
В Kotlin 1.6.0 можно опробовать предварительную версию нового менеджера памяти Kotlin/Native. Это приближает нас к устранению различий между платформами JVM и Native и обеспечивает единообразную работу разработчиков в многоплатформенных проектах.
Одно из заметных изменений — отложенная инициализация свойств верхнего уровня, как в Kotlin/JVM. Свойство верхнего уровня инициализируется при первом обращении к свойству или функции верхнего уровня из того же файла. Этот режим также включает глобальную межпроцедурную оптимизацию (только для выпускных двоичных файлов), которая устраняет избыточные проверки инициализации.
Недавно мы опубликовали публикацию в блоге о новом менеджере памяти. Прочитайте её, чтобы узнать о текущем состоянии нового менеджера памяти и посмотреть демонстрационные проекты, или перейдите сразу к инструкциям по миграции, чтобы попробовать его самостоятельно. Проверьте работу нового менеджера памяти в своих проектах и оставьте отзыв в нашей системе отслеживания задач — YouTrack.
Поддержка Xcode 13
Kotlin/Native 1.6.0 поддерживает Xcode 13 — последнюю версию Xcode. Обновите Xcode и продолжайте работу над проектами Kotlin для операционных систем Apple.
Компиляция целевых платформ Windows на любом хосте
Начиная с версии 1.6.0 для компиляции целевых платформ Windows mingwX64 и mingwX86 хост Windows не нужен. Их можно компилировать на любом хосте, поддерживающем Kotlin/Native.
Обновления LLVM и компоновщика
Мы переработали используемую Kotlin/Native внутреннюю зависимость от LLVM. Это принесло ряд преимуществ, в том числе:
Обновление LLVM до версии 11.1.0.
Уменьшение размера зависимости. Например, в macOS теперь она занимает около 300 МБ вместо 1200 МБ в предыдущей версии.
Удалена зависимость от библиотеки
ncurses5, недоступной в современных дистрибутивах Linux.
Помимо обновления LLVM, в Kotlin/Native для целевых платформ MingGW теперь используется компоновщик LLD (компоновщик из проекта LLVM). По сравнению с ранее используемым компоновщиком ld.bfd он даёт ряд преимуществ, позволяет повысить производительность выполнения созданных двоичных файлов и поддерживать кэширование компилятора для целевых платформ MinGW. Обратите внимание: LLD требует библиотек импорта для компоновки DLL. Подробнее см. в этой теме на Stack Overflow.
Улучшения производительности
В Kotlin/Native 1.6.0 представлены следующие улучшения производительности:
Время компиляции: кэширование компилятора по умолчанию включено для целевых платформ
linuxX64иiosArm64. Это ускоряет большинство компиляций в режиме отладки (кроме первой). Согласно измерениям, скорость компиляции в наших тестовых проектах выросла примерно на 200%. Кэширование компилятора доступно для этих целевых платформ начиная с Kotlin 1.5.0 с использованием дополнительных свойств Gradle; теперь их можно удалить.Время выполнения: благодаря оптимизации сгенерированного кода LLVM перебор массивов с помощью циклов
forтеперь выполняется до 12% быстрее.
Единый ABI плагинов компилятора с бэкендами JVM и JS IR
В предыдущих версиях авторам плагинов компилятора приходилось предоставлять отдельные артефакты для Kotlin/Native из-за различий в ABI.
Начиная с версии 1.6.0, плагин Kotlin Multiplatform Gradle может использовать для Kotlin/Native встраиваемый JAR-файл компилятора, применяемый для бэкендов JVM и JS IR. Это шаг к унификации процесса разработки плагинов компилятора: теперь для Native и других поддерживаемых платформ можно использовать одни и те же артефакты плагинов компилятора.
Это предварительная версия поддержки, для использования которой необходимо явно включить соответствующую настройку. Чтобы начать использовать универсальные артефакты плагинов компилятора для Kotlin/Native, добавьте следующую строку в gradle.properties: kotlin.native.useEmbeddableCompilerJar=true.
В будущем мы планируем использовать встраиваемый JAR-файл компилятора для Kotlin/Native по умолчанию, поэтому нам очень важно узнать, как работает предварительная версия.
Если вы автор плагина компилятора, попробуйте этот режим и проверьте, работает ли он с вашим плагином. В зависимости от структуры плагина могут потребоваться действия по миграции. Инструкции по миграции приведены в этой задаче YouTrack; оставьте свой отзыв в комментариях.
Подробные сообщения об ошибках при сбоях компоновки klib
Теперь компилятор Kotlin/Native выводит подробные сообщения об ошибках компоновки klib. В них приводятся чёткие описания ошибок, а также информация о возможных причинах и способах их устранения.
Например:
-
1.5.30:
e: java.lang.IllegalStateException: IrTypeAliasSymbol expected: Unbound public symbol for public kotlinx.coroutines/CancellationException|null[0] <stack trace>
-
1.6.0:
e: The symbol of unexpected type encountered during IR deserialization: IrClassPublicSymbolImpl, kotlinx.coroutines/CancellationException|null[0]. IrTypeAliasSymbol is expected. This could happen if there are two libraries, where one library was compiled against the different version of the other library than the one currently used in the project. Please check that the project configuration is correct and has consistent versions of dependencies. The list of libraries that depend on "org.jetbrains.kotlinx:kotlinx-coroutines-core (org.jetbrains.kotlinx:kotlinx-coroutines-core-macosx64)" and may lead to conflicts: <list of libraries and potential version mismatches> Project dependencies: <dependencies tree>
Переработанный API обработки необработанных исключений
Мы унифицировали обработку необработанных исключений во всём средстве выполнения Kotlin/Native и сделали обработку по умолчанию доступной в виде функции processUnhandledException(throwable: Throwable) для пользовательских сред выполнения, например kotlinx.coroutines. Эта обработка применяется и к исключениям, выходящим за пределы операции в Worker.executeAfter(), но только при использовании нового менеджера памяти.
Улучшения API коснулись также обработчиков, заданных с помощью setUnhandledExceptionHook(). Ранее такие обработчики сбрасывались после вызова средой выполнения Kotlin/Native с необработанным исключением, а программа всегда немедленно завершалась. Теперь эти обработчики можно использовать несколько раз. Если программа должна всегда завершаться при необработанном исключении, не задавайте обработчик необработанных исключений (setUnhandledExceptionHook()) либо обязательно вызывайте terminateWithUnhandledException() в конце обработчика. Это позволит отправить исключения в стороннюю службу отчётов о сбоях (например, Firebase Crashlytics), а затем завершить программу. Исключения, выходящие за пределы main(), и исключения, пересекающие границу взаимодействия, всегда приводят к завершению программы, даже если обработчик не вызвал terminateWithUnhandledException().
Kotlin/JS
Мы продолжаем работу над стабилизацией бэкенда IR компилятора Kotlin/JS. Теперь в Kotlin/JS есть возможность отключить загрузку Node.js и Yarn.
Использование предварительно установленных Node.js и Yarn
Теперь при сборке проектов Kotlin/JS можно отключить загрузку Node.js и Yarn и использовать уже установленные на хосте версии. Это удобно для сборки на серверах без подключения к интернету, например на серверах CI.
Чтобы отключить загрузку внешних компонентов, добавьте следующие строки в build.gradle(.kts):
-
Yarn:
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> { rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().download = false // or true for default behavior }rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin) { rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension).download = false } -
Node.js:
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> { rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().download = false // or true for default behavior }rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin) { rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension).download = false }
Плагин Kotlin Gradle
В Kotlin 1.6.0 уровень устаревания класса KotlinGradleSubplugin изменён на 'ERROR'. Этот класс использовался для написания плагинов компилятора. В следующих выпусках мы удалим этот класс. Вместо него используйте класс KotlinCompilerPluginSupportPlugin.
Мы удалили параметр сборки kotlin.useFallbackCompilerSearch, а также параметры компилятора noReflect и includeRuntime. Параметр компилятора useIR скрыт и будет удалён в будущих выпусках.
Подробнее о параметрах компилятора, поддерживаемых в настоящее время, в плагине Kotlin Gradle.
Стандартная библиотека
Новая версия стандартной библиотеки 1.6.0 стабилизирует экспериментальные функции, вводит новые и унифицирует поведение библиотеки на разных платформах:
Новые функции readline
В Kotlin 1.6.0 появились новые функции для обработки стандартного ввода: readln() и readlnOrNull().
Предыдущие версии |
Альтернатива в версии 1.6.0 |
Использование |
|---|---|---|
|
|
Читает строку из stdin и возвращает ее либо выбрасывает |
|
|
Читает строку из stdin и возвращает ее либо возвращает |
Мы считаем, что отказ от необходимости использовать !! при чтении строки улучшит впечатления новичков и упростит обучение Kotlin. Чтобы название операции чтения строки соответствовало названию ее аналога println(), мы решили сократить имена новых функций до 'ln'.
println("What is your nickname?")
val nickname = readln()
println("Hello, $nickname!")
fun main() {
//sampleStart
var sum = 0
while (true) {
val nextLine = readlnOrNull().takeUnless {
it.isNullOrEmpty()
} ?: break
sum += nextLine.toInt()
}
println(sum)
//sampleEnd
}
Существующая функция readLine() получит более низкий приоритет, чем readln() и readlnOrNull(), в автодополнении кода IDE. Инспекции IDE также будут рекомендовать использовать новые функции вместо устаревшей readLine().
В будущих версиях мы планируем постепенно объявить функцию readLine() устаревшей.
Стабильная функция typeOf()
В версии 1.6.0 функция typeOf() получила статус стабильной, что позволяет закрыть один из важных пунктов дорожной карты.
Начиная с версии 1.3.40, typeOf() была доступна на платформе JVM как экспериментальный API. Теперь ее можно использовать на любой платформе Kotlin и получать представление KType любого типа Kotlin, который компилятор может вывести:
inline fun <reified T> renderType(): String {
val type = typeOf<T>()
return type.toString()
}
fun main() {
val fromExplicitType = typeOf<Int>()
val fromReifiedType = renderType<List<Int>>()
}
Стабильные функции создания коллекций
В Kotlin 1.6.0 функции создания коллекций получили статус стабильных. Коллекции, возвращаемые этими функциями, теперь сериализуемы в состоянии только для чтения.
Теперь функции buildMap(), buildList() и buildSet() можно использовать без аннотации opt-in:
fun main() {
//sampleStart
val x = listOf('b', 'c')
val y = buildList {
add('a')
addAll(x)
add('d')
}
println(y) // [a, b, c, d]
//sampleEnd
}
Стабильный API Duration
Класс Duration, предназначенный для представления длительности в разных единицах времени, получил статус стабильного. В версии 1.6.0 в API Duration внесены следующие изменения:
Первый компонент функции
toComponents(), которая разбивает длительность на дни, часы, минуты, секунды и наносекунды, теперь имеет типLongвместоInt. Раньше, если значение не помещалось в диапазонInt, его приводили к этому диапазону. ТипLongпозволяет разбить любое значение из диапазона длительности, не отсекая значения, которые не помещаются вInt.Перечисление
DurationUnitтеперь является самостоятельным типом, а не псевдонимом типаjava.util.concurrent.TimeUnitна JVM. Мы не нашли убедительных примеров, когдаtypealias DurationUnit = TimeUnitмог бы быть полезен. Кроме того, предоставление APITimeUnitчерез псевдоним типа может сбить с толку пользователейDurationUnit.-
В ответ на отзывы сообщества мы возвращаем свойства-расширения, например
Int.seconds. Однако мы хотим ограничить область их применения, поэтому помещаем их в companion-объект классаDuration. IDE по-прежнему может предлагать расширения при автодополнении и автоматически добавлять импорт из companion-объекта, но в будущем мы планируем ограничить такое поведение случаями, когда ожидается типDuration.import kotlin.time.Duration.Companion.seconds fun main() { //sampleStart val duration = 10000 println("There are ${duration.seconds.inWholeMinutes} minutes in $duration seconds") // There are 166 minutes in 10000 seconds //sampleEnd }Мы рекомендуем заменить ранее добавленные функции companion-объекта, такие как
Duration.seconds(Int), и устаревшие расширения верхнего уровня, напримерInt.seconds, новыми расширениями вDuration.Companion.
Разделение Regex на последовательность
Функции Regex.splitToSequence(CharSequence) и CharSequence.splitToSequence(Regex) получили статус стабильных. Они разделяют строку по совпадениям с заданным регулярным выражением, но возвращают результат в виде последовательности, чтобы все операции над результатом выполнялись лениво:
fun main() {
//sampleStart
val colorsText = "green, red, brown&blue, orange, pink&green"
val regex = "[,\\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
// or
// val mixedColor = colorsText.splitToSequence(regex)
.onEach { println(it) }
.firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"
//sampleEnd
}
Операции циклического сдвига битов целых чисел
В Kotlin 1.6.0 функции rotateLeft() и rotateRight() для манипуляций с битами получили статус стабильных. Эти функции циклически сдвигают двоичное представление числа влево или вправо на указанное количество битов:
fun main() {
//sampleStart
val number: Short = 0b10001
println(number
.rotateRight(2)
.toString(radix = 2)) // 100000000000100
println(number
.rotateLeft(2)
.toString(radix = 2)) // 1000100
//sampleEnd
}
Изменения replace() и replaceFirst() в JS
До выхода Kotlin 1.6.0 функции Regex replace() и replaceFirst() работали по-разному в Java и JS, если строка замены содержала ссылку на группу. Чтобы обеспечить одинаковое поведение на всех целевых платформах, мы изменили их реализацию в JS.
Вхождения ${name} или $index в строке замены заменяются подстроками, соответствующими захваченным группам с указанным индексом или именем:
$index— первая цифра после '$' всегда считается частью ссылки на группу. Последующие цифры добавляются вindexтолько в том случае, если в результате получается действительная ссылка на группу. Потенциальными компонентами ссылки на группу считаются только цифры от '0' до '9'. Обратите внимание, что индексация захваченных групп начинается с '1'. Группа с индексом '0' обозначает всё совпадение.-
${name}—nameможет состоять из латинских букв 'a'–'z', 'A'–'Z' или цифр '0'–'9'. Первый символ должен быть буквой. -
Чтобы включить следующий символ в строку замены как буквальный, используйте символ обратной косой черты
\:fun main() { //sampleStart println(Regex("(.+)").replace("Kotlin", """\$ $1""")) // $ Kotlin println(Regex("(.+)").replaceFirst("1.6.0", """\\ $1""")) // \ 1.6.0 //sampleEnd }Если строку замены нужно обработать как обычную строку, можно использовать
Regex.escapeReplacement().
Улучшения существующего API
-
В версии 1.6.0 добавлена инфиксная функция-расширение для
Comparable.compareTo(). Теперь для сравнения двух объектов по порядку можно использовать инфиксную форму:class WrappedText(val text: String) : Comparable<WrappedText> { override fun compareTo(other: WrappedText): Int = this.text compareTo other.text } Функция
Regex.replace()в JS также больше не является inline, что позволяет унифицировать ее реализацию на всех платформах.Функции String
compareTo()иequals(), а также функция CharSequenceisBlank()теперь работают в JS точно так же, как и на JVM. Ранее наблюдались отличия при обработке символов, не относящихся к ASCII.
Устаревшие элементы
В Kotlin 1.6.0 мы начинаем цикл объявления устаревшими с предупреждения для некоторых API стандартной библиотеки, доступных только в JS.
Функции строк concat(), match() и matches()
Чтобы объединить строку со строковым представлением другого заданного объекта, используйте
plus()вместоconcat().Чтобы найти все вхождения регулярного выражения во входных данных, используйте
findAll()класса Regex вместоString.match(regex: String).Чтобы проверить, соответствует ли регулярное выражение всей входной строке, используйте
matches()класса Regex вместоString.matches(regex: String).
Функция sort() для массивов с функциями сравнения
Мы объявили устаревшей функцию Array<out T>.sort() и инфиксные функции ByteArray.sort(), ShortArray.sort(), IntArray.sort(), LongArray.sort(), FloatArray.sort(), DoubleArray.sort() и CharArray.sort(), которые сортировали массивы в порядке, заданном функцией сравнения. Для сортировки массивов используйте другие функции стандартной библиотеки.
См. раздел порядок элементов в коллекциях.
Инструменты
Kover — инструмент анализа покрытия кода для Kotlin
В Kotlin 1.6.0 мы представляем Kover — плагин для Gradle, предназначенный для агентов анализа покрытия кода Kotlin IntelliJ и JaCoCo. Он работает со всеми конструкциями языка, включая inline-функции.
Подробнее о Kover можно узнать в его репозитории на GitHub или из этого видео:
Coroutines 1.6.0-RC
kotlinx.coroutines 1.6.0-RC доступна и содержит несколько функций и улучшений:
Поддержка нового менеджера памяти Kotlin/Native
Появление API представлений диспетчера, позволяющего ограничивать параллелизм без создания дополнительных потоков
Переход с целевой версии Java 6 на Java 8
kotlinx-coroutines-testс новым переработанным API и поддержкой мультиплатформенностиПоявление
CopyableThreadContextElement, который предоставляет корутинам потокобезопасный доступ на запись к переменнымThreadLocal
Подробнее см. в списке изменений.
Переход на Kotlin 1.6.0
IntelliJ IDEA и Android Studio предложат обновить плагин Kotlin до версии 1.6.0, как только она станет доступна.
Чтобы перенести существующие проекты на Kotlin 1.6.0, измените версию Kotlin на 1.6.0 и повторно импортируйте проект Gradle или Maven. Узнайте, как обновить проект до Kotlin 1.6.0.
Чтобы начать новый проект на Kotlin 1.6.0, обновите плагин Kotlin и запустите мастер создания проекта: Файл | Создать | Проект.
Новый компилятор командной строки можно скачать на странице релиза на GitHub.
Kotlin 1.6.0 — это версия с новыми функциями, поэтому она может содержать изменения, несовместимые с кодом, написанным для предыдущих версий языка. Подробный список таких изменений см. в руководстве по совместимости с Kotlin 1.6.
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew16.html