[Перевод] Kotlin получил почти настоящие статики

Ребята из Jetbrains работают над расширением механизма компаньонов (companions), чтобы открыть новые возможности для организации кода и улучшить совместимость между различными платформами. В этой статье мы расскажем о новых возможностях и дадим предварительные рекомендации по миграции.
Блоки-компаньоны и расширения
Во многих языках программирования существует понятие членов класса или типа — функциональности, которая относится не к отдельным экземплярам класса, а к самому классу. К этой категории часто относятся константы, вспомогательные функции и фабричные методы.
val v1 = Vector(1.0, 2.0) // обычный вектор
val v2 = Vector.ZERO // константа нулевого вектора
val v3 = Vector.unit(angle = PI / 2) // единичный вектор с заданным угломРанее для определения таких членов использовались объекты-компаньоны (companion objects). Начиная с Kotlin 2.5.0, для этой цели также можно использовать экспериментальные блоки-компаньоны (companion blocks). Синтаксически они очень похожи на объекты-компаньоны, однако принципиально отличаются способом компиляции.
data class Vector(val x: Double, val y: Double) {
companion {
val ZERO = Vector(0.0, 0.0)
}
}При этом такие члены необязательно определять непосредственно внутри самого класса. Экспериментальные расширения-компаньоны (companion extensions) позволяют объявлять новые члены класса для любого типа, даже если вы не управляете его исходным кодом.
companion fun Vector.unit(angle: Double) = Vector(cos(angle), sin(angle))Блоки-компаньоны и расширения-компаньоны спроектированы таким образом, чтобы преодолеть ограничения, присущие объектам-компаньонам.
Во-первых, расширения-компаньоны можно определять для любого класса или интерфейса — независимо от того, есть ли у вас доступ к его исходному коду, написан ли он на Kotlin или Java и существует ли у него объект-компаньон.
Во-вторых, механизм их компиляции аналогичен тому, как обрабатываются статические члены на других платформах. Например, на JVM блоки-компаньоны компилируются в статические члены. Это открывает дополнительные возможности для Kotlin Multiplatform: теперь можно объявлять ожидаемые (expect) члены блока-компаньона и предоставлять их фактические (actual) реализации с помощью Java-класса, содержащего статические члены.
Если вы хотите подробнее узнать об этой будущей возможности языка, вся необходимая информация содержится в соответствующем предложении KEEP.
Использование экспериментальных компаньонов
Блоки-компаньоны и расширения-компаньоны — это экспериментальные возможности, доступные начиная с Kotlin 2.5.0-Beta1. Для их использования необходимо передать компилятору дополнительный флаг:
-Xcompanion-blocks— разрешает использование блоков-компаньонов.-Xcompanion-blocks-and-extensions— разрешает использование как блоков-компаньонов, так и расширений-компаньонов.
При включении второго флага компилятор создаёт бинарные файлы с пометкой предварительной версии (pre-release). Это означает, что библиотеки, использующие расширения-компаньоны, нельзя будет подключать в качестве зависимостей до тех пор, пока эта возможность не станет стабильной.
На предоставление блоков-компаньонов такое ограничение не распространяется. Однако для использования этих блоков в зависимых проектах всё равно потребуется включить соответствующую экспериментальную возможность.
А что будет с существующими объектами-компаньонами?
Возникает закономерный вопрос: какую роль будут играть объекты-компаньоны в языке, где появились блоки-компаньоны и расширения-компаньоны? На него есть два ответа:
С одной стороны, в большинстве случаев вместо объектов-компаньонов лучше использовать блоки-компаньоны. Поэтому при написании нового кода предпочтение можно отдавать именно им.
С другой стороны, существуют сценарии, в которых без объектов-компаньонов не обойтись. Например, если компаньон должен реализовывать определённый интерфейс, единственным вариантом остаётся объект-компаньон, поскольку при компиляции он превращается в полноценный класс.
При этом переходить на новый механизм необязательно. Объекты-компаньоны остаются неотъемлемой частью Kotlin, и их дальнейшая поддержка полностью гарантирована.
Если же вы решите перейти на блоки-компаньоны, в большинстве случаев будет достаточно удалить ключевое слово object. Однако следует учитывать, что после такого изменения потребуется перекомпилировать как сам проект, так и весь код, который от него зависит.
Кроме того, некоторые инструменты экосистемы пока могут не поддерживать блоки-компаньоны.

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.