Writing Idiomatic Kotlin
In this page:
Preferring Expressions Over Statements
Idiomatic Kotlin favors expression-based constructs -- if/when as expressions, single-expression functions -- over verbose statement-based equivalents copied from other languages.
Example: Preferring Expressions Over Statements
fun describe(n: Int) = when {
n < 0 -> "negative"
n == 0 -> "zero"
else -> "positive"
}
// Entry point: execution of the program starts here
fun main() {
// Print `describe(-5)` to the console, with a trailing newline
println(describe(-5))
// Print `describe(0)` to the console, with a trailing newline
println(describe(0))
// Print `describe(10)` to the console, with a trailing newline
println(describe(10))
}
Login to try C/C++/Java/PHP code in the editor
Using Data Classes Instead of Manual Boilerplate
Reaching for data class instead of manually writing equals(), hashCode(), and toString() is a hallmark of idiomatic Kotlin, saving both code and potential bugs.
Example: Using Data Classes Instead of Manual Boilerplate
// Define a data class `Point`
data class Point(val x: Int, val y: Int)
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `p1`, set to `Point(1, 2)`
val p1 = Point(1, 2)
// Declare a read-only variable `p2`, set to `Point(1, 2)`
val p2 = Point(1, 2)
// Print "Equal: ${p1 == p2}, toString: $p1" to the console, with a trailing newline
println("Equal: ${p1 == p2}, toString: $p1")
}
Login to try C/C++/Java/PHP code in the editor
Embracing Null Safety Idioms
Idiomatic Kotlin uses ?., ?:, and safe scope functions instead of manual null checks copied from languages without built-in null safety.
Example: Embracing Null Safety Idioms
// Define the function `greetOrDefault` taking `name` and returning a String
fun greetOrDefault(name: String?): String = name?.let { "Hello, $it!" } ?: "Hello, stranger!"
// Entry point: execution of the program starts here
fun main() {
// Print `greetOrDefault("Kotlin")` to the console, with a trailing newline
println(greetOrDefault("Kotlin"))
// Print `greetOrDefault(null)` to the console, with a trailing newline
println(greetOrDefault(null))
}
Login to try C/C++/Java/PHP code in the editor
Favoring Immutability and Small Functions
Idiomatic Kotlin leans toward val over var, read-only collections over mutable ones by default, and small, well-named functions (including extensions) over large, do-everything utility classes.
Example: Favoring Immutability and Small Functions
fun List<Int>.average2(): Double = if (isEmpty()) 0.0 else sum().toDouble() / size
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `scores`, set to `listOf(80, 90, 70)`
val scores = listOf(80, 90, 70)
// Print "Average: ${scores.average2()}" to the console, with a trailing newline
println("Average: ${scores.average2()}")
}
Login to try C/C++/Java/PHP code in the editor
- Writing Java-style code in Kotlin, such as manual getter/setter methods or verbose null checks, instead of using Kotlin's built-in properties and null-safety operators.
- Ignoring expression-oriented features like
if/whenas expressions and single-expression functions, resulting in unnecessarily verbose code. - Overusing advanced features (like heavy operator overloading or excessive DSLs) where plain, simple code would be clearer.
- Prefer
valovervar, expression bodies over verbose blocks, and built-in null-safety operators over manual null checks. - Use data classes for simple data holders instead of manually writing
equals/hashCode/toString. - Favor immutable collections and small, focused extension functions over sprawling utility classes.
- Idiomatic code favors clarity and conciseness together, not brevity at the expense of readability.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: