[英]Kotlin How to create dynamic Object
在 javascript 我们可以做这样的事情
function putritanjungsari(data){ console.log(data.name) } let data = { name:"putri", div:"m4th" } putritanjungsari(data)
In kotlin, i'am creating a function that accept an object as parameter then read it's properties later, how to do that in kotlin that targeting JVM?
如果我理解您的问题是正确的,那么您正在尝试使用一个变量将键与某个值或 undefined(null in kt) 相关联(如果没有找到)。 您正在寻找Map如果您不知道您想要什么类型,您可以制作任何类型的 map? 所以
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)
请注意,您不能在此处添加新密钥或编辑任何数据,默认 map 是不可变的。 有 MutableMap (实现方式相同,只是它有一个放置新数据的方法)
您可以应用属性设计模式来解决您的问题。
这是它在 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?>
的原因:
NAME - 3
和NAME(true)
不会编译)您必须使用Any之后,您必须使用 object,像这样
private fun putritanjungsari(data : Any){
if(data is Mydata){
var data = data as? Mydata
data.name
}
}
Kotlin 是静态类型语言,因此需要精确定义或明确推断参数类型(例如,Groovy 至少通过两种方式解决此问题)。 但是对于 JS 互操作性 Kotlin 提供了动态类型。
同时,在您的特定情况下,您可以将数据结构键入 kt 的 Map 并且不要与严格的类型争论。
只是为了灵感。 在 Kotlin 中,您可以创建临时对象:
val adHoc = object {
var x = 1
var y = 2
}
println(adHoc.x + adHoc.y)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.