Skip to content

Kotlin 2.0 – Key Syntax Changes

In this article I will describe the main innovations in the syntax compared to previous versions.

The full list of new features can be found here:

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

// Kotlin 1.x:

class User(
  val name: String
)

fun greet(user: User) {
  with(user) {
    println("Hello, $name")
  }
}

fun main() {
  greet(User("Alice"))
}

// Kotlin 2.0:
// Now you can add contexts for functions, 
// to explicitly specify their dependencies at the API level:

class User(
  val name: String
)

context(User)

fun greet() {
  println("Hello, $name")
}

fun main() {
  val user = User("Alice")
  with(user) {
    greet()
  }
}

They work similarly, but the new name better reflects their essence, and also provides additional optimizations when using such classes on the JVM.

// Kotlin 1.x:

inline class Name(
  val value: String
)


// Kotlin 2.0:

@JvmInline
value class Name(
  val value: String
)
// Kotlin 1.x:

sealed class Shape {

  class Circle(
    val radius: Double
  ) : Shape()

  class Square(
    val side: Double
  ) : Shape()

}

// Kotlin 2.0:
// now you can make sealed interfaces

sealed interface Shape

class Circle(
  val radius: Double
) : Shape

class Square(
  val side: Double
) : Shape
fun process(
  action: () -> Unit
) {
  action()
}

fun main() {
  process {
    return@process println("Lambda with label")
  }
}
val list = listOf(1, 2, 3)

val doubled = list.mapNotNull { 
  if (it > 1) it * 2 
  else null 
}
sealed class Shape

class Circle(
  val radius: Double
) : Shape()

class Square(
  val side: Double
) : Shape()

fun describeShape(shape: Shape): String = when (shape) {
  is Circle -> "Circle with radius ${shape.radius}"
  is Square -> "Square with side ${shape.side}"
}
data class Person(
  val name: String, 
  val age: Int
)

fun main() {
  val (name, age) = Person("Alice", 30)
  println("Name: $name, Age: $age")
}

For loops can now destructure objects directly within the loop body

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")
  }
}
class Container<T>(val value: T) {
  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