Сопоставьте ключевые значения с классом данных в Kotlin - PullRequest
0 голосов
/ 31 января 2020

как я могу установить свойства класса данных по его имени. Например, у меня есть необработанный ответ HTTP GET

propA=valueA
propB=valueB

и класс данных в Kotlin

data class Test(var propA: String = "", var propB: String = ""){}

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

val test: Test = Test()
rawResp?.split('\n')?.forEach { item: String ->
    run {
         val keyValue = item.split('=')
         TODO
    }
}

В JavaScript Я могу сделать следующее

response.split('\n').forEach(item => {
    let keyValue = item.split('=');
    this.test[keyValue[0]] = keyValue[1];
 });

Есть ли аналогичный способ в Kotlin?

Ответы [ 2 ]

1 голос
/ 31 января 2020

К слову, для меня не было ясно, представляет ли каждая строка экземпляр Test или нет. Так что

Если нет.

fun parse(rawResp: String): Test = rawResp.split("\n").flatMap { it.split("=") }.let { Test(it[0], it[1]) }

Если да.

fun parse(rawResp: String): List<Test> = rawResp.split("\n").map { it.split("=") }.map { Test(it[0], it[1]) }

Для нулевой безопасной альтернативы вы можете использовать nullableString.orEmpty()...

0 голосов
/ 31 января 2020

Вы не можете легко сделать это в Kotlin так же, как в JavaScript (если вы не готовы самостоятельно обрабатывать отражение), но есть возможность использовать функцию Kotlin, называемую Делегированные свойства (в частности, вариант использования Сохранение свойств на карте этой функции).

Вот пример, указывающий c для кодирования в исходном вопросе:

class Test(private val map: Map<String, String>) {
    val propA: String by map
    val propB: String by map

    override fun toString() = "${javaClass.simpleName}(propA=$propA,propB=$propB)"
}

fun main() {
    val rawResp: String? = """
        propA=valueA
        propB=valueB
        """.trimIndent()

    val props = rawResp?.split('\n')?.map { item ->
        val (key, value) = item.split('=')
        key to value
    }?.toMap() ?: emptyMap()

    val test = Test(props)

    println("Property 'propA' of test is: ${test.propA}")
    println("Or using toString: $test")
}

Это выводит:

Property 'propA' of test is: valueA
Or using toString: Test(propA=valueA,propB=valueB)

К сожалению, вы не можете использовать классы данных с делегированием свойства так, как вы ожидаете, поэтому вам нужно «заплатить цену» и определить переопределенные методы (toString, equals, hashCode) самостоятельно, если они вам нужны.

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