Сьогодні в меню — новий Kotlin 2.0

💡 Усі статті, обговорення, новини про Mobile — в одному місці. Приєднуйтесь до Mobile спільноти!

Всім привіт! З вами знову Бодька. Можете пригадати мене за циклом статей про Kotlin Multiplatform. Давно я тут не був, і багато чого за цей час сталось, як-от реліз Kotlin 2.0, довгоочікуваного K2, вибух екосистеми Kotlin Multiplatform новими бібліотеками Jetpack, а також розв’язання багатьох накипілих проблем із Compose, особливо Compose for Web.

Ну, і заспойлерили деякі майбутні фічі мови Kotlin. Ух, у мене аж апетит до мультиплатформи знову прокинувся.

Аперитив — майбутні фічі

Почнімо з тих самих фічей. Нам їх, як у мемі про рибов, тільки показують. Вони поки що в розробці, і з’являться у Kotlin 2.1 або 2.2.

dataarg-класи

У вас часто буває, що доводиться механічно копіпастити певний набір аргументів, оскільки вони потрібні кожній функції або конструктору? Тепер для цієї проблеми є розв’язання. Наприклад, у вас у Compose-коді є низка кнопок різного стилю, і всі ж потрібні! Тому можна написати dataarg-клас вигляду:

dataarg class ButtonArgs(
    modifier: Modifier = Modifier,
    onClick: () -> Unit = {  },
    contents: @Composable () -> Unit
)

...і використати ось так:

@Composable
fun MaterialOneButton(args: ButtonArgs) {
    /* ... */
}
@Composable
fun MetroButton(args: ButtonArgs) {
    /* ... */
}
@Composable
fun iOSButton(args: ButtonArgs) {
    /* ... */
}

...і цей код працюватиме так само як і функції зі звичайними повторюваними сигнатурами:

fun MaterialOneButton(
    modifier: Modifier = Modifier,
    onClick: () -> Unit = {  },
    contents: @Composable () -> Unit
) {
    /* ... */
}

@Composable
fun MetroButton(
    modifier: Modifier = Modifier,
    onClick: () -> Unit = {  },
    contents: @Composable () -> Unit
) {
    /* ... */
}

@Composable
fun iOSButton(
    modifier: Modifier = Modifier,
    onClick: () -> Unit = {  },
    contents: @Composable () -> Unit
) {
    /* ... */
}

...і якщо доведеться масово міняти сигнатури, то достатньо просто змінити те, що є у dataarg-класу. З’явиться... Невідомо, коли.

Guards (ґарди)

Напевно, вам всім відома ситуація, коли є довгий when statement:

val status: Status = ...
val doRickroll = true
when {
    status == Status.OK -> "Okay, move on."
    status == Status.BadRequest -> "Open me! https://www.flickr.com/photos/girliemac/6540669737/in/album-72157628409467125/"
    status == Status.Teapot && doRickroll -> "Open me! https://youtu.be/dQw4w9WgXcQ"
    else -> "I'm a teapot"
}

...і ви бажаєте його скоротити через when with subject:

 when (status) {
    Status.OK -> "Okay, move on."
    Status.BadRequest -> "Open me! https://www.flickr.com/photos/girliemac/6540669737/in/album-72157628409467125/"
    Status.Teapot && doRickroll -> "Open me! https://youtu.be/dQw4w9WgXcQ"
    else -> "I'm a teapot"
}

...і стрічка коду з рікроллом підкреслена червоним. Механізм ґардів дозволяє обійти це обмеження і зарікроллити нашого юзера:

Status.Teapot if (doRickroll) -> "Open me! https://youtu.be/dQw4w9WgXcQ"

Never gonna give you up, never gonna let you down... Ой. З’явиться у Kotlin 2.1 як бета-фіча, а зараз доступна як експериментальна.

Context receivers parameters

Маєте такий код:

withAutoClose {
    val lyrics = open(File("Never gonna give you up - Lyrics.txt"))
}

interface AutoCloseScope

fun withAutoClose(block: AutoCloseScope.() -> Unit)

fun AutoCloseScope.open(file: File): InputStream

...але навіть завзятим користувачам Python не подобається вкладеність функцій. А що, як спробувати це:

withAutoClose {
    val lyrics = File("Never gonna give you up - Lyrics.txt").open()
}

Виглядає неймовірно, але щоб зробити цей код валідним, треба більше контексту. AutoCloseScope.open() уже має ресивер, тому нам потрібно вказати додатковий контекст у withAutoClose():

fun withAutoClose(block: context(_: AutoCloseScope).() -> Unit)

...та скористатись ним:

context(scope: AutoCloseScope)
fun File.open(): InputStream

Все, тепер ця функція виглядає красиво, ідіоматично та приязно до аналізу IDE. Вже доступна як експериментальна фіча, буде в беті у Kotlin 2.2

І хоч би за всім цим цукром хоч трохи мови залишилось, кхм...

Основна страва — надшвидкий K2

У самому K2 нічого, крім оптимізації, особливого для більшості програмістів нема. Є багато змін для тих, хто пише плагіни компілятора та IDE, але про них я тут не розповім. У JetBrains кажуть, що вони скоротили час компіляції Kotlin-коду навпіл (отже, ніякої кави під час ./gradlew build clean) та зробили фронтенд K2 більш «платформно-агностичним», тобто менш залежним від усіх платформ.

Заміряти на своєму комп’ютері та перевірити їхню інформацію достеменно я не зміг, інакше написання цієї статті зайняло б кілька тижнів. Але я помітив відчутну різницю у швидкості компіляції «чистих» та «релізних» збірок та меншу, але все одно помітну при інкрементальній компіляції (вона найчастіше трапляється, коли ви трішки змінили код і хочете перезапустити програму, щоб побачити зміни наживо).

А, ще дещо. Іще рік тому в Android Studio та IntelliJ IDEA з’явився режим K2 — під час його використання для аналізу та індексації проєктів використовується той самий фронтенд, що і для компіляції. Той самий K2, що майже унеможливлює false positives та прискорює індексацію... в теорії.

Бо на практиці режим K2 нестабільний. У мене його не вдалось завести навіть на базових шаблонах з IntelliJ. До речі, особливо смішно те, що в Android Studio у режимі K2 не працює... розпіарений плагін Gemini, який Google так любить і обожнює.

Друга страва — екосистема Kotlin Multiplatform

Єдине, що із ним сталось — так це вибух у площині first-party-бібліотек. Kandy (візуалізація даних) та Dataframe (перемелення даних) дають широкі можливості для дата-саєнтистів — тих самих, що відкрили ящик Пандори та запустили хайп довкола генеративного ШІ.

Стандартна бібліотека, Coroutines, IO, Serialization — усе те саме, чим вони були раніше, але більше, краще, швидше, вище, сильніше. Покращена документація, більше common-типів, покращена сумісність з кількома платформами одночасно. Вийшов із бети й Kover — CodeCov, але вибудований із задатком у Kotlin Multiplatform. Оновили гайдлайни написання API.

Десерт — солоденький Compose (обережно, десерт ду-у-уже жирний)

Але що Google обожнює точно більше за ШІ, так це Compose. Бо там нарешті придумали розв’язання проблеми плутанини із Compose Compatibility Map. Інструкція проста, як п’ять центів. Зберігайте. А тепер готуйтесь:

  • Compose for iOS — вийшов з альфи. Тепер він у Beta. Не буде таких штурмів під час міграції на нові версії;
  • Jetpack Navigation, Lifecycle View Models, ресурси — тепер частина Compose Multiplatform на всіх платформах (нарешті!);
  • Compose for Web — більше не експериментальний. Тепер він у стадії альфа. Більшість core API реалізовано. Працює на Kotlin/Wasm.

Попереджав — буде жирно.

Бонусний смаколик — новий маскот!

Представили нового маскота. На відміну від попереднього, він має ім’я — Коуді (Kodee). Ви тільки подивіться на цю милоту!

А що це було?

Це був Бодя. Він розказав вам, що приніс із собою реліз Kotlin 2.0, а саме — про багато чудових змін в екосистемі, потужну оптимізацію, поступовий вихід з експериментального стану багатьох чудових проєктів та багато чого іншого. Повторімо?

  1. K2 прискорив збірку проєктів «з нуля» удвічі.
  2. Пообіцяли швидше робити нові фічі для мови.
  3. Можна помацати Guards та Context parameters, анонсували класи dataarg.
  4. З’явився тулкіт для дата-саєнтистів. Тепер графіки можна робити на Kotlin завдяки Kandy та Dataframe.
  5. Тепер відсоток покриття коду тестами можна рахувати і в мультиплатформі завдяки Kover.
  6. Google взялись за голову та послали якомога далі той триклятий Compatibility Map.
  7. Compose Multiplatform стабілізується та процвітає.
  8. І найважливіше, найбільш тектонічна зміна в екосистемі Kotlin, що грозиться влаштувати людству апокаліпсис болючіший, ніж той, що застали динозаври — новий маскот.

Смачного, не обпечіться. Зміни дуже гарячі! Розкажіть, що смакує вам найбільше. Бувайте!

👍ПодобаєтьсяСподобалось9
До обраногоВ обраному2
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Мені здається котлін потроху стає більш схожим на скалу — якісь фічі, щоб писати на півтора символи меньше, все частіше я бачу (про бекенд) «Sping/JPA це не kotlin way, ktor та функціональнe програмування — це kotlin way», у той час Java стає тією better-java яким був kotlin з початку.

Kotlin Multiplatform взагалі мертвонароджений ІМХО. Але це конкуренція, конкуренція — це добре.

не бачив жодного проекту на котліні повністю у функціональному стилі. Зазвичай це трохи ООП, трохи функціональний підхід. І нормально воно може жити разом, не бачу в цьому нічого поганого.

та доки усе мігрує на нові JDK...

А що не так із KMP? Є нормальні альтернативи натіву? Я от думаю на нього із flutter перейти.

Підписатись на коментарі