Как преобразовать расширение в член? - PullRequest
0 голосов
/ 12 января 2019

Kotlin позволяет расширять конкретные экземпляры класса общего типа. Например, предположим, что у меня есть следующий класс Foo с функциями расширения Foo<Int>.bar() и Foo<String>.bar():

class Foo<T>(t: T) {
  val a: String = "bar"
  val b: Int = 111
}

fun Foo<Int>.bar() = a
fun Foo<String>.bar() = b

fun main(args: Array<String>) {
  val stringBar: String = Foo(1).bar()
  val intBar: Int = Foo("").bar()
}

Возможно ли добиться такого поведения без функций расширения, и если да, то как мне преобразовать функции расширения в члены? Возможно ли это без переименования или изменения сигнатур типа?

Ответы [ 3 ]

0 голосов
/ 12 января 2019

Нет, это невозможно (принятый в настоящее время ответ совсем не похож на ваш код).

0 голосов
/ 12 января 2019

Используя рефлексию, вам не нужно самостоятельно сопоставлять тип и свойство.

Функция-член propertyValue() вернет значение первого свойства, которое имеет тип универсального параметра или null.

class Foo {
    val a: String = "bar"
    val b: Int = 111

    inline fun <reified T> propertyValue() = Foo::class.memberProperties.firstOrNull {
        it.returnType == T::class.createType()
    }?.get(this)
}

Foo().propertyValue<Int>()) // 111
Foo().propertyValue<String>()) // bar
Foo().propertyValue<Double>()) // null

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

0 голосов
/ 12 января 2019

Вы можете создать встроенную функцию-члена с reified универсальным параметром:

class Foo<T>(t: T) {
    val a: String = "bar"
    val b: Int = 111

    inline fun <reified T, E> member(): E? {
        var r: E? = null
        when(T::class) {
            String::class -> r = b as E
            Int::class -> r = a as E
        }
        return r
    }
}

fun main(args: Array<String>) {
   val str = Foo(1).member<Int, String>()
   val i = Foo("").member<String, Int>()
}

Но расширение функции лучше в вашем случае: они безопасны от типов, более кратки и удобочитаемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...