Kotlin Как создать динамический объект - PullRequest
0 голосов
/ 03 октября 2019

В javascript мы можем сделать что-то вроде этого

function putritanjungsari(data){
	console.log(data.name)
}

let data = {
	name:"putri",
	div:"m4th"
}
putritanjungsari(data)

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

Ответы [ 4 ]

1 голос
/ 03 октября 2019

Если я правильно понял ваш вопрос, вы пытаетесь создать переменную, которая связывает ключи с некоторым значением или неопределенным (ноль в кт), если ничего не найдено. Вы ищете Карта Если вы не знаете, какие типы вы хотите, вы можете сделать карту типа Any? Итак,

Map<String, Any?>

Что также можно обнулять

Map<String, Any>

Если вы не хотите обнулять

Ваш код, например:

fun putritanjungsari(data: Map<String, Any?>){
print(data["name"]) 
}

val data: Map<String, Any?> =mapOf(        
"name" to "putri",
"div" to "m4th" 
)
putritanjungsari(data)

Обратите внимание, что вы не можете добавлять новые ключи или редактировать какие-либо данные здесь, карта по умолчанию неизменна. Существует MutableMap (который реализован так же, только у него есть метод для добавления новых данных)

0 голосов
/ 03 октября 2019

Вы можете применить шаблон проектирования свойства для решения вашей проблемы.

Вот его реализация в Kotlin:

interface DynamicProperty<T> {
    fun cast(value: Any?): T
    fun default(): T

    companion object {
        inline fun <reified T> fromDefaultSupplier(crossinline default: () -> T) =
            object : DynamicProperty<T> {
                override fun cast(value: Any?): T = value as T
                override fun default(): T = default()
            }

        inline operator fun <reified T> invoke(default: T) = fromDefaultSupplier { default }

        inline fun <reified T> required() = fromDefaultSupplier<T> {
            throw IllegalStateException("DynamicProperty isn't initialized")
        }

        inline fun <reified T> nullable() = DynamicProperty<T?>(null)
    }
}

operator fun <T> DynamicProperty<T>.invoke(value: T) = DynamicPropertyValue(this, value)

data class DynamicPropertyValue<T>(val property: DynamicProperty<T>, val value: T)

class DynamicObject(vararg properties: DynamicPropertyValue<*>) {
    private val properties = HashMap<DynamicProperty<*>, Any?>().apply {
        properties.forEach { put(it.property, it.value) }
    }

    operator fun <T> get(property: DynamicProperty<T>) =
        if (properties.containsKey(property)) property.cast(properties[property])
        else property.default()

    operator fun <T> set(property: DynamicProperty<T>, value: T) = properties.put(property, value)
    operator fun <T> DynamicProperty<T>.minus(value: T) = set(this, value)
}

fun dynamicObj(init: DynamicObject.() -> Unit) = DynamicObject().apply(init)

Вы можете определить свои свойства этими способами:

val NAME = DynamicProperty.required<String>() // throws exceptions on usage before initialization
val DIV = DynamicProperty.nullable<String>() // has nullable type String?
val IS_ENABLED = DynamicProperty(true) // true by default

Теперь вы можете использовать их:

fun printObjName(obj: DynamicObject) {
    println(obj[NAME])
}

val data = dynamicObj {
    NAME - "putri"
    DIV - "m4th"
}
printObjName(data)

// throws exception because name isn't initialized
printObjName(DynamicObject(DIV("m4th"), IS_ENABLED(false)))

Причины использовать DynamicObject вместо Map<String, Any?>:

  1. Тип-безопасность (NAME - 3 и NAME(true) не будут компилироваться)
  2. При использовании свойств не требуется приведение
  3. Вы можете определить, что должна делать программа, если свойство не инициализировано
0 голосов
/ 03 октября 2019

Kotlin является языком со статической типизацией, поэтому он требовал, чтобы тип параметра был точно определен или однозначно выведен (например, Groovy рассматривает случай по крайней мере двумя способами). Но для совместимости с JS Kotlin предлагает динамический тип .

Между тем, в вашем конкретном случае вы можете набрать data структуру в Map kt и не спорить со строгой типизацией.

0 голосов
/ 03 октября 2019

Вы должны использовать Любой , и после этого вы должны разыграть свой объект, как этот

private fun putritanjungsari(data : Any){
    if(data is Mydata){
        var data =  data as? Mydata
        data.name
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...