我有以下代码:
class Mapped(var data:Map<String,String>){
val firstName:String by data
}
如果Mapped
的使用方法如下,这样可以正常工作:
val mapped = Mapped(mapOf("firstName" to "initialFirstName"))
println(mapped.firstName); // prints "initialFirstName"
然而,由于data
属性是可变的,我们可以改变它的值,即:
mapped.data = mapOf("firstName" to "updated");
但firstName
属性仍保留"initialFirstName"
。
是否解决了这个,known/documented虽然出乎意料(对我而言)的行为?
答案 0 :(得分:6)
在解决问题KT-5870,KT-9772之前,您可以执行以下操作:
operator fun <V, V1 : V> (() -> Map<in String, V>).getValue(thisRef: Any?, property: KProperty<*>): V1 {
val map = this()
return map[property.name] as V1
}
然后可以按如下方式使用:
class Mapped(var data:Map<String,String>){
val firstName:String by { data }
}
以上不能很好地处理可空性。这是一个改进的版本:
operator fun <V, V1 : V> (() -> Map<in String, V>).getValue(thisRef: Any?, property: KProperty<*>): V1 {
val map = this()
val key = property.name
@Suppress("UNCHECKED_CAST")
val value = map[key] as V1
if (property.returnType.isMarkedNullable) {
return value
} else {
if(value != null){
return value
}
if(map.containsKey(key)){
throw KotlinNullPointerException("Property baking map returned null value for key '$key' for non nullable property: $property")
} else {
throw KotlinNullPointerException("Property baking map has no key '$key' for non nullable property $property")
}
}
}