Реліз Kotlin 2.0: найцікавіші функції

БлогЩось не зрозуміле
Maksym Dudka,,
0
0
1
#beginners#javascript#LinkedIn#microservices#programming#softwaredevelopment

Реліз Kotlin 2.0: найцікавіші функції

Привіт усім! Мене звати Максим Дудка, я Java Engineer. Вийшов реліз Kotlin 2.0, і я вирішив поговорити про нього. Приємного читання!

Статтю також можна прочитати англійською.

Для тих, хто не чув про Kotlin (не певен, чи залишились такі люди), — це статично типізована мова програмування, розроблена компанією JetBrains, що набула величезного хайпу з моменту свого створення. Відома своїми сучасними можливостями, лаконічним, скажемо так, цукровим синтаксисом та безшовною інтеграцією з Java. Kotlin став улюбленцем серед розробників.

Випуск Kotlin 2.0 знаменує собою значний етап у розвитку мови, вводячи безліч нових покращень, спрямованих на підвищення продуктивності розробників, безпеки коду та загальної продуктивності. У цій статті я підсвітив найцікавіші, як на мене, функції Kotlin 2.0.

Sealed when statements

Однією з найбільш очікуваних функцій у Kotlin 2.0 є вдосконалення when statements за допомогою sealed-класів. Хоча when statements завжди були потужними, тепер вони забезпечують вичерпну перевірку для sealed-класів, роблячи їх ще більш надійними та виразними.

sealed class Result {
    data class Success(val data: String) : Result()
    data class Error(val message: String) : Result()
    object Loading : Result()
}

fun handleResult(result: Result) = when (result) {
    is Result.Success -> println("Data: ${result.data}")
    is Result.Error -> println("Error: ${result.message}")
    Result.Loading -> println("Loading...")
}

Ця нова фіча забезпечує покриття всіх можливих випадків sealed-класу прямо під час компіляції, підвищуючи безпеку коду та його читабельність.

Sealed interfaces

У Kotlin 2.0 введені sealed-інтерфейси для доповнення sealed-класів. Sealed-інтерфейси дозволяють обмежити реалізацію інтерфейсу фіксованим набором типів. Ця функція підвищує безпеку типів та спрощує pattern matching.

sealed interface Shape

data class Circle(val radius: Double) : Shape
data class Rectangle(val width: Double, val height: Double) : Shape

fun describeShape(shape: Shape): String = when (shape) {
    is Circle -> "Коло з радіусом ${shape.radius}"
    is Rectangle -> "Прямокутник з шириною ${shape.width} та висотою ${shape.height}"
}

Покращений вивід типів

Kotlin уже з перших версій мав вивід типів, але Kotlin 2.0 вводить значні покращення у можливості виведення типів, компілятор може точніше визначати типи в складних сценаріях, зменшуючи потребу помітно вказувати тип. Також компілятор може ефективніше визначати generic-типи в коді, схожому на такий:

fun <T, R> List<T>.filterAndMap(predicate: (T) -> Boolean, transform: (T) -> R): List<R> {
    return this.filter(predicate).map(transform)
}

val numbers = listOf(1, 2, 3, 4, 5)
val result = numbers.filterAndMap({ it % 2 == 0 }, { it.toString() })

Advanced functional programming features

Kotlin завжди був відомий своїми можливостями функціонального програмування. Kotlin 2.0 розвиває ці можливості, вводячи кілька розширених функцій функціонального програмування, які спрощують роботу з функціями вищого порядку та лямбдами. Що таке функції вищого порядку, композиція функцій я покажу в наступних прикладах, що цікаві з точки зору синтаксичних можливостей Kotlin.

Функції вищого порядку

Функції вищого порядку — це функції, які приймають інші функції як параметри або повертають функції. Вони є фундаментальною концепцією у функціональному програмуванні.

fun <T> List<T>.customFilter(predicate: (T) -> Boolean): List<T> {
    val result = mutableListOf<T>()
    for (item in this) {
        if (predicate(item)) {
            result.add(item)
        }
    }
    return result
}

val numbers = listOf(1, 2, 3, 4, 5)
// Використання функції вищого порядку для фільтрації парних чисел
val evenNumbers = numbers.customFilter { it % 2 == 0 }
println("Парні числа: $evenNumbers")

Тут customFilter є функцією вищого порядку, яка приймає лямбду як параметр. Лямбда використовується для фільтрації списку на основі заданої умови.

Композиція функцій

Композиція функцій — це прийом у функціональному програмуванні, який об’єднує кілька функцій в одну. Kotlin 2.0 спрощує композицію функцій та створення багаторазових блоків коду.

fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}

val add5 = { x: Int -> x + 5 }
val multiplyBy2 = { x: Int -> x * 2 }
// Композиція функцій для створення нової функції
val add5AndMultiplyBy2 = compose(multiplyBy2, add5)
println("Результат композиції add5 і multiplyBy2: ${add5AndMultiplyBy2(10)}")

У цьому прикладі compose є функцією вищого порядку, яка приймає дві функції як параметри та повертає їх композицію. Композована функція add5AndMultiplyBy2 спочатку додає п’ять до вхідного значення, а потім множить результат на два.

Context Receivers

Context Receivers у Kotlin 2.0 дозволяють створювати більш гнучкі та повторно використовувані функції, визначаючи необхідні контексти для функції. Ця функція особливо корисна для DSL (Domain-Specific Languages) та функцій у певних контекстах.

class HtmlContext {
    private val elements = mutableListOf<String>()

    fun div(content: String) {
        elements.add("<div>$content</div>")
    }

    fun build(): String = elements.joinто
fun header(content: String) {
    div("Header: $content")
}

context(HtmlContext)
fun footer(content: String) {
    div("Footer: $content")
}

// Використання
fun main() {
    val htmlContext = HtmlContext()
    with(htmlContext) {
        header("Welcome to My Site")
        footer("© 2024 My Company")
    }
    println(htmlContext.build())
}

Value classes

Value classes у Kotlin 2.0 забезпечують спосіб визначення «легких» класів, які не мають накладних витрат на аллокацію об’єктів.

@JvmInline
value class UserId(val id: String)

fun greetUser(userId: UserId) {
    println("Привіт, користувач ${userId.id}")
}

fun main() {
    val userId = UserId("12345")
    greetUser(userId)
}

Краща підтримка мультиплатформенності

Kotlin 2.0 додатково покращує свої можливості багатоплатформенності, дозволяючи розробникам шарити більшу кількість коду між різними платформами (JVM, JavaScript і Native).

Вдосконалення стандартної бібліотеки

Стандартна бібліотека Kotlin також зазнала кількох покращень у версії 2.0. Додані нові функції та класи для спрощення звичайних завдань та підвищення продуктивності розробників. Одним з помітних доповнень є монада Result, яка забезпечує більш виразний спосіб обробки очікуваного флоу та помилок.

fun divide(a: Int, b: Int): Result<Int> {
    return if (b != 0) {
        Result.success(a / b)
    } else {
        Result.failure(IllegalArgumentException("Ділення на нуль"))
    }
}

val result = divide(10, 2)
result.onSuccess { println("Результат: $it") }
       .onFailure { println("Помилка: ${it.message}") }

Компілятор K2

Новий компілятор K2 у Kotlin 2.0 розроблений для того, щоб бути швидшим, ефективнішим і більш розширюваним, ніж його попередник. Він спрямований на покращення діагностики помилок, покращення часу компіляції та розширену підтримку багатоплатформенних проєктів. Під капотом компілятор K2 вводить більш модульну архітектуру, що дозволяє використовувати інкрементну компіляцію для покращення швидкості компіляцї, отож розробники з проєктами з великою кодовою базою матимуть менше часу, щоб бити байдики, поки проєкт збирається :)

Висновок

Kotlin 2.0 — це значний крок вперед для мови; він вводить безліч нових функцій та покращень, які підвищують продуктивність розробників, безпеку коду та загальну продуктивність. Від Sealed when steatements та покращеного виведення типів до Context receivers і Value-класів, Kotlin 2.0 надає потужні інструменти, що відповідають сучасним потребам розробки. Компілятор K2, покращена підтримка IDE, кращі можливості багатоплатформенності, підвищена сумісність і різні покращення продуктивності ще більше закріплюють позиції Kotlin як одного з найкращих виборів для Android та Back-end розробників.

Happy coding!


Категорії
Теги
Популярні статті