Extension Functions

Adding Functions to Existing Classes

An extension function adds a new function to a class you do not own (like String or Android's View) without changing its source or inheriting from it. Write the type (the receiver) before the function name; inside, this is the receiver.

Example

fun String.isPalindrome(): Boolean {
    val clean = this.lowercase().filter { it.isLetterOrDigit() }
    return clean == clean.reversed()
}

fun Int.isEven() = this % 2 == 0

fun String.initials() = split(" ").filter { it.isNotBlank() }.joinToString("") { it.first().uppercase() }

fun main() {
    println("Malayalam".isPalindrome())
    println("Kotlin".isPalindrome())
    println(10.isEven())
    println("abhinav kumar gunda".initials())
}

Output

true
false
true
AKG

Extensions on Your Own and Generic Types

Example

data class Product(val name: String, val price: Double)

fun Product.withGst(rate: Double = 18.0) = price + price * rate / 100

fun <T> List<T>.secondOrNull(): T? = if (size >= 2) this[1] else null

fun main() {
    val phone = Product("Phone", 10000.0)
    println(phone.withGst())
    println(phone.withGst(5.0))
    println(listOf("a", "b", "c").secondOrNull())
    println(listOf(1).secondOrNull())
}

Output

11800.0
10500.0
b
null

Note: Most of the Kotlin standard library is written as extensions: filter, map, joinToString, let... are all extension functions.

Exercise

Exercise: Write an extension fun String.maskPhone() that keeps only the last 4 digits: "9876543210" becomes "******3210".

Show answer
fun String.maskPhone() = "*".repeat(length - 4) + takeLast(4)

fun main() {
    println("9876543210".maskPhone()) // ******3210
}