kotlinadvanced
Inline Functions and Reified Generics
Use inline functions for zero-overhead abstractions: reified type parameters, crossinline, and noinline.
kotlinPress ⌘/Ctrl + Shift + C to copy
import kotlin.time.measureTimedValue
import kotlin.time.Duration
// Reified type parameter — access type info at runtime
inline fun <reified T> String.parseAs(): T? = when (T::class) {
Int::class -> toIntOrNull() as? T
Long::class -> toLongOrNull() as? T
Double::class -> toDoubleOrNull() as? T
Boolean::class -> toBooleanStrictOrNull() as? T
String::class -> this as T
else -> null
}
// Type-safe JSON-like casting
inline fun <reified T> Any?.safeCast(): T? = this as? T
// Reified type checking
inline fun <reified T> List<*>.filterIsType(): List<T> =
filterIsInstance<T>()
// Inline for performance — lambda inlined at call site
inline fun <T> retry(
times: Int = 3,
delay: Long = 100,
block: (attempt: Int) -> T
): T {
var lastException: Exception? = null
repeat(times) { attempt ->
try {
return block(attempt)
} catch (e: Exception) {
lastException = e
Thread.sleep(delay * (attempt + 1))
}
}
throw lastException!!
}
// crossinline — can't return from enclosing function
inline fun transaction(crossinline block: () -> Unit) {
println("BEGIN")
try {
block()
println("COMMIT")
} catch (e: Exception) {
println("ROLLBACK: ${e.message}")
}
}
// noinline — prevent inlining specific lambda
inline fun measured(
label: String,
noinline onComplete: ((Duration) -> Unit)? = null,
block: () -> Unit
) {
val (_, duration) = measureTimedValue { block() }
println("$label took: $duration")
onComplete?.invoke(duration)
}
// Inline class (value class) — zero overhead wrapper
@JvmInline
value class Email(val value: String) {
init {
require(value.contains("@")) { "Invalid email" }
}
val domain get() = value.substringAfter("@")
}
@JvmInline
value class UserId(val value: Long)
@JvmInline
value class Meters(val value: Double) {
operator fun plus(other: Meters) = Meters(value + other.value)
operator fun times(factor: Double) = Meters(value * factor)
fun toKilometers() = value / 1000.0
}
fun main() {
// Reified parsing
val port = "8080".parseAs<Int>()
val rate = "3.14".parseAs<Double>()
val flag = "true".parseAs<Boolean>()
println("port=$port, rate=$rate, flag=$flag")
// Type filtering
val mixed: List<Any> = listOf(1, "hello", 2.0, "world", 3)
val strings: List<String> = mixed.filterIsType()
val ints: List<Int> = mixed.filterIsType()
println("Strings: $strings, Ints: $ints")
// Retry
var attempts = 0
val result = retry(times = 3) { attempt ->
attempts++
if (attempt < 2) throw RuntimeException("Fail $attempt")
"Success on attempt $attempt"
}
println("$result (tried $attempts times)")
// Transaction
transaction {
println("Doing work...")
// return // crossinline prevents non-local return
}
// Value classes — zero overhead
val email = Email("alice@test.com")
println("Domain: ${email.domain}")
val distance = Meters(1500.0) + Meters(500.0)
println("${distance.value}m = ${distance.toKilometers()}km")
}Use Cases
- Type-safe parsing and casting utilities
- Zero-overhead wrapper types
- Performance-critical higher-order functions
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinintermediate
Inline Functions and Reified Generics
Use inline functions with reified type parameters for type-safe operations without reflection.
Best for: Type-safe operations without reflection overhead
#kotlin#inline
kotlinadvanced
Generics — Variance, Bounds, and Type Projections
Master Kotlin generics: in/out variance, upper bounds, type projections, and generic constraints.
Best for: Type-safe generic APIs and containers
#kotlin#generics
kotlinintermediate
Value Classes — Zero-Cost Wrappers
Create type-safe wrappers with value classes: no runtime overhead, domain identifiers, and units.
Best for: Type-safe domain identifiers
#kotlin#value-class
kotlinadvanced
Type Class Pattern with Generics
Implement type class patterns in Kotlin: ad-hoc polymorphism, generic serializers, and extension-based dispatch.
Best for: Ad-hoc polymorphism without inheritance
#kotlin#generics