The following sample code is from a webpage. I understand that these vars _id, city and country get value by delegate.
I can't understand how map: MutableMap pass value to these vars _id, city and country ?
Do I must pass value of these key to map first ? such as map["_id"]=132L, map["city"]="Wuha" and map["country"]="USA"?
What happened if there is no map["_id"] ? will the code var _id: Long by map
cause error?
class CityForecast(val map: MutableMap<String, Any?>, val dailyForecast: List<DayForecast>) {
var _id: Long by map
var city: String by map
var country: String by map
constructor(id: Long, city: String, country: String, dailyForecast: List<DayForecast>)
: this(HashMap(), dailyForecast) {
this._id = id
this.city = city
this.country = country
}
}
First, you need to understand how delegated property works. Object does not own the delegated property directly. It only owns the delegate. For example, var _id: Long by map
is actually look like
var _id: Long
get() {
val value = map["_id"] as? Long
if (value == null)
throw Excecption()
return value
}
set(value) {
map["_id"] = value
}
Do I must pass value of these key to map first ? such as map["_id"]=132L, map["city"]="Wuha" and map["country"]="USA"?
No, it is a run-time check, just like lateinit
.
What happened if there is no map["_id"] ? will the code var _id: Long by map cause error?
Of course, there will be an exception.
Note that this is NOT recommended for normal class. It is designed for JSON deserialization (I still prefer GSON though). It is not recommended because you are creating potential run-time exception which can be avoid, including missing value and type checking.
Also, you should use mutableMapOf()
instead of HashMap()
if you does not need HashMap()
explicitly.