如果映射中不存在,则映射抛出NoTouchElementException的Kotlin委托属性
我将kotlin对象定义为:如果映射中不存在,则映射抛出NoTouchElementException的Kotlin委托属性,kotlin,Kotlin,我将kotlin对象定义为: data class UserUpdateRequest(val map: Map<String, Any?>) { @get:Email val email: String? by map val firstName: String? by map val lastName: String? by map } 数据类UserUpdateRequest(val-map:map){ @获取:电子邮件 val电子邮件:字符串
data class UserUpdateRequest(val map: Map<String, Any?>) {
@get:Email
val email: String? by map
val firstName: String? by map
val lastName: String? by map
}
数据类UserUpdateRequest(val-map:map){
@获取:电子邮件
val电子邮件:字符串?按地图
val firstName:字符串?按映射
val lastName:字符串?按映射
}
这很好,所以我遇到的问题是属性是可以为空的,当我访问一个属性时,比如通过执行instance.email
它会抛出一个NoTouchElementException
,如果映射中没有设置该属性
相反,如果它返回null
,则会更方便,因为它是可选的/可空的。在不编写我自己的委托的情况下,有什么方法可以实现这一点吗?您基本上可以使用为委托包装映射的扩展,以便它执行lambda来计算缺席键上的值:
data class UserUpdateRequest(val map: Map<String, Any?>) {
private val defaultMap = map.withDefault { null }
@get:Email
val email: String? by defaultMap
val firstName: String? by defaultMap
val lastName: String? by defaultMap
}
数据类UserUpdateRequest(val-map:map){
private val defaultMap=map.withDefault{null}
@获取:电子邮件
val电子邮件:字符串?按默认映射
val firstName:字符串?按默认映射
val lastName:String?按默认映射
}
请注意,简单的defaultMap.get(key)
和defaultMap[key]
查询不由此包装器处理,它只影响defaulMap.getValue(key)
调用(委托实现也会使用这些调用)。下面是一个委托实现,如果您想更多地控制代理的工作并了解其工作方式
演示如何在您的场景中使用它的第一步:
在上面的例子中,实际上我们调用
initialMap["lastName"] = "Genericname"
如果变量名和对应的键不同,甚至可以将键作为参数传递。
通过这种方法,您可以在getValue和setValue函数中自行处理值访问
希望这对任何人都有帮助
fun <R>valueFromMap(key: (KProperty<*>) -> String = KProperty<*>::name,
map: Map<String, Any?>): ReadWriteProperty<Any, R?>{
val myMap = map.toMutableMap()
return object : ReadWriteProperty<Any, R?> {
override fun getValue(thisRef: Any, property: KProperty<*>): R? {
return (myMap.getOrDefault(key(property), null) as? R)?: return null
}
override fun setValue(thisRef: Any, property: KProperty<*>, value: R?) {
if(value == null){
myMap.remove(key(property))
} else {
myMap[key(property)] = value
}
}
}
request.lastName = "Genericname"
initialMap["lastName"] = "Genericname"