Roman Kryvolapov Engineering Blog

Kotlin 2.0 – основни нововъведения в синтаксиса

В тази статия ще опиша основните нововъведения в синтаксиса спрямо предишните версии (част от тях са се появили много преди Kotlin 2.0 — версията е посочена в примерите).

Пълният списък с нововъведения може да се намери тук:

https://kotlinlang.org/docs/whatsnew20.html

Context Receivers

Kotlin
// Kotlin 1.x:
class User(
val name: String
)
fun greet(user: User) {
with(user) {
println("Hello, $name")
}
}
fun main() {
greet(User("Alice"))
}
// Kotlin 1.6.20+ (експериментално, флаг -Xcontext-receivers; в 2.2 са заменени с context parameters):
// Сега могат да се добавят контексти за функциите,
// за да се указват изрично зависимостите им на ниво API:
class User(
val name: String
)
context(User)
fun greet() {
println("Hello, $name")
}
fun main() {
val user = User("Alice")
with(user) {
greet()
}
}

Value classes (преименувани inline класове)

Работят по същия начин, но новото име по-добре отразява същността им, а освен това са предоставени допълнителни оптимизации при използването на такива класове на JVM (от Kotlin 1.5)

Kotlin
// Преди Kotlin 1.5:
inline class Name(
val value: String
)
// Kotlin 1.5 и по-нови:
@JvmInline
value class Name(
val value: String
)

Sealed Interface

Kotlin
// Преди Kotlin 1.5:
sealed class Shape {
class Circle(
val radius: Double
) : Shape()
class Square(
val side: Double
) : Shape()
}
// Kotlin 1.5 и по-нови:
// вече могат да се правят sealed интерфейси
sealed interface Shape
class Circle(
val radius: Double
) : Shape
class Square(
val side: Double
) : Shape

Етикети за ламбди и анонимни функции

Kotlin
fun process(
action: () -> Unit
) {
action()
}
fun main() {
process {
return@process println("Ламбда с етикет") // етикетите съществуват от Kotlin 1.0
}
}

Поддръжка на нови операции с колекции

Kotlin
val list = listOf(1, 2, 3)
val doubled = list.mapNotNull { // mapNotNull съществува от Kotlin 1.0
if (it > 1) it * 2
else null
}

Поддръжка на нов синтаксис за сравняване с образец в when

Kotlin
sealed class Shape
class Circle(
val radius: Double
) : Shape()
class Square(
val side: Double
) : Shape()
fun describeShape(shape: Shape): String = when (shape) { // is проверките в when съществуват от Kotlin 1.0; guard условията (if) се появиха в 2.1 като експериментални
is Circle -> "Circle with radius ${shape.radius}"
is Square -> "Square with side ${shape.side}"
}

Мултидекларации за класове с operator

Kotlin
data class Person(
val name: String,
val age: Int
)
fun main() {
val (name, age) = Person("Alice", 30) // деструктурирането съществува от Kotlin 1.0
println("Name: $name, Age: $age")
}

For цикли и подобрения с деструктуриране

for циклите могат да деструктурират обекти направо в заглавието на цикъла (от Kotlin 1.0)

Kotlin
data class Person(
val name: String,
val age: Int
)
fun main() {
val people = listOf(
Person("Alice", 30),
Person("Bob", 25)
)
for ((name, age) in people) {
println("$name is $age years old")
}
}

Поддръжка на подобрени оператори за generics и генерични типове

Kotlin
class Container<T>(val value: T) { // претоварването на оператори работи от Kotlin 1.0
operator fun plus(other: Container<T>): Container<T> {
return Container(other.value)
}
}
fun main() {
val container1 = Container(10)
val container2 = Container(20)
println(container1 + container2)
}

Copyright: Roman Kryvolapov