Syntax
Kotlin syntax tour: variables, nullables, classes, data classes, extension functions, sealed types, coroutines.
Kotlin — syntax tour
EXAMPLE
// ===== Variables =====
val pi = 3.14 // immutable (use by default)
var count = 0 // mutable
count += 1
// ===== Nullables =====
val maybe: String? = null
val len = maybe?.length ?: 0 // safe call + Elvis
val forced = maybe!!.length // force; throws NPE if null
// ===== Strings =====
val name = "Alex"
val g = "Hello $name (${name.length})"
val multi = """
multi
line
""".trimIndent()
// ===== Collections =====
val nums = listOf(1, 2, 3) // read-only
val mutNums = mutableListOf(1)
val ages = mapOf("Alex" to 30)
val tags = setOf("vip", "beta")
nums.map { it * it }
nums.filter { it > 1 }
nums.sum(); nums.average()
// ===== Control flow =====
if (count > 0) { /* ... */ } else { /* ... */ }
for (n in 1..10) println(n)
while (count < 5) count++
// when (Kotlin's switch + pattern match):
val size = when {
count == 0 -> "none"
count < 10 -> "small"
count < 100 -> "medium"
else -> "large"
}
val type = when (val v: Any = 42) {
is Int -> "int $v"
is String -> "str $v"
null -> "nothing"
else -> "other"
}
// ===== Classes =====
class User(val name: String, var email: String) {
fun display() = "$name <$email>"
}
// ===== Data classes =====
data class Order(val id: Int, val total: Long)
// equals, hashCode, toString, copy generated.
val o = Order(1, 4995)
val o2 = o.copy(total = 5000)
// ===== Sealed classes (closed hierarchies) =====
sealed class Result<out T> {
data class Ok<T>(val value: T) : Result<T>()
data class Err(val msg: String) : Result<Nothing>()
}
// when on sealed types is exhaustive:
fun show(r: Result<Int>) = when (r) {
is Result.Ok -> println(r.value)
is Result.Err -> println("err ${r.msg}")
}
// ===== Functions =====
fun add(a: Int, b: Int): Int = a + b
fun greet(name: String = "world") = "Hi $name"
// Extension functions:
fun String.snakeCase(): String = this.lowercase().replace(' ', '_')
println("Hello World".snakeCase())
// Higher-order:
fun <T, R> List<T>.toMap(transform: (T) -> Pair<R, T>): Map<R, T> =
this.associate(transform)
// ===== Coroutines =====
import kotlinx.coroutines.*
suspend fun fetch(): String { delay(100); return "done" }
fun main() = runBlocking {
val results = listOf(async { fetch() }, async { fetch() }).awaitAll()
println(results)
}
// ===== Patterns to internalise =====
// - val by default; var only when you mean it
// - Data classes for value carriers
// - Sealed classes for closed type hierarchies
// - Coroutines for structured concurrency
// ===== Pitfalls =====
// - !! everywhere -> defeats null-safety
// - Mutating shared state across coroutines without sync
// - Forgetting Dispatchers.IO on blocking calls
// - Mixing Java + Kotlin null conventions without @Nullable annotations
Why it matters
Kotlin is Java with sharp edges removed. val / var, nullable types, when, data classes, sealed types, extension functions, coroutines — small reflexes that compound. The language rewards immutable defaults and exhaustive pattern matching.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
fun greet(name: String): String = "Hello, $name!"
fun main() { println(greet("Ada")) }
Try it Yourself »
Discussion
Loading…