Ссылка на вложенную собственность Котлин

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")) } 

Как я мог бы получить ссылку на вложенную собственность с хорошим и безопасным, в идеале, как это (это не работает):

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

Я подумал, что могу сделать функцию расширения, например: House::door.nested(Door::name) но Im застрял в реализации.

Для вашей гипотетической nested функции попробуйте следующее:

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

Теперь вы можете сделать именно то, что вы спросили:

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

Вы можете его также связать:

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

Чистый трюк здесь заключается в том, как Kotlin позволяет ссылаться на свойство как функцию.

nested функция по существу является функциональной композицией. Он принимает функцию a -> b и функцию b -> c и записывает их в новую функцию a -> c . Вы часто найдете, что он называется compose в стандартных библиотеках.

Kotlin не имеет функционального состава в качестве стандарта, но есть библиотеки, если вам нужно что-то более сложное, чем это.