Extension Properties = A Mashup

An extension property looks like a regular property with custom accessors, except that it is declared on an existing class, the way an extension function is:

val <T> Map<String, T>.something: T?
  get() = this["something"]

val stuff = mapOf("something" to "This is the 'something' value")

fun main() {
  println(stuff.something)
}

This is the same basic scenario as the custom getter example from above, except that we move it to be an extension property on Map<String, T> for some generic type T. If you ignore the generics, the syntax is pretty much the same as it is for extension functions: ClassName.propertyName to declare that this property is to be added to ClassName.

With an extension val property, we have to provide a custom getter. The value of the property has to come from somewhere, and it is up to us to define what that “somewhere” is. In this case, we just obtain the value of the "something" entry in the Map, if there is one.

If you use var instead of val, you will need to provide both the custom getter and the custom setter:

var <T> MutableMap<String, T>.something: T
  get() = this["something"] ?: throw IllegalArgumentException("we do not have something")
  set(value) { this["something"] = value }

fun main() {
  val stuff = mutableMapOf<String, String?>("something" to "This is the 'something' value")

  stuff.something = "This is different"
  println(stuff.something)
}

You might wonder why the custom getter works. [] syntax on a Map returns a nullable type (T?), and our custom getter needs to return T. So, using the Elvis operator, we throw an exception if [] returns null. The reason why the compiler then realizes that our custom getter returns a T has to do with what throw evaluates to, as we will see later in the book.

Extension properties, therefore, are little more than extension functions, just ones that provide users with property syntax instead of function syntax.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.