简体   繁体   中英

Kotlin nested property reference

data class House(var name: String = "House", var door: Door = Door())
data class Door(var name: String = "Door")

fun test() {
   val testHouse = House("My house", Door(name = "My door"))
}

How could I get nested property reference nice and safe, ideally like this (this doesn't work though):

   val houseDoorName = House::door::name
   println(houseDoorName.get(testHouse)) //My door

I figured I could maybe do extension function, something like: House::door.nested(Door::name) but Im stuck with the implementation.

For your hypothetical nested function, try this:

fun <A, B, C> ((A) -> B).nested(getter : (B) -> C) : (A) -> C = { getter(this(it)) }

Now you can do exactly what you asked:

val houseDoorName = House::door.nested(Door::name)
val house = House(door = Door(name = "My door"))
println(houseDoorName(house)) // prints "My door"

You can chain it, too:

val doorNameLength = House::door.nested(Door::name).nested(String::length)

The neat trick here is the way Kotlin allows a property reference to be treated as a function.

The nested function is essentially a functional composition. It takes a function a -> b and a function b -> c , and composes them into a new function a -> c . You'll often find it called compose in standard libraries.

Kotlin doesn't have function composition as standard, but there are libraries out there if you need anything more complex than this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM