Learning Kotlin: by

Note * This is the 25th post in a multipart series. If you want to read more, see our series index * Koans used here are 34 and 35

The fourth set of Koans examines properties, and the first two focus on getters and setters. If you're coming from another programming language, these should work as you expect. This post will explore the amazing by keyword in the third and fourth examples. The by keyword lets us delegate the getter/setter to a separate class, allowing common patterns to be extracted and reused. Out of the box, there are five built-in options—which I’ll cover in their own posts—but for now, let’s build our own delegate class.

In this example, we can assign any value, but the result we always get is HAHAHA. We could store the result in the instance and return the assigned value, but we don’t have to. The key takeaway is that we’ve centralized the logic for our properties in one reusable place instead of scattering it across multiple getters and setters.

import kotlin.reflect.KProperty

class User {
    var name: String by Delegate()
    var eyeColour: String by Delegate()
}

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty): String {
        println("$thisRef, thank you for delegating '${property.name}' to me!")
        return "HAHAHA"
    }

    operator fun setValue(thisRef: Any?, property: KProperty, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}

fun main(args: Array<String>) {
    val user = User()
    user.name = "Robert"
    user.eyeColour = "Green"
    println("My word ${user.name} but your eyes are ${user.eyeColour}")
}