2016-05-07 41 views
6

我有下面的代碼:物業代表團可變地圖出爐

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儘管意外(對我)的行爲?

回答

6

直到問題KT-5870KT-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") 
     } 
    } 
}