How does MutableMap<String, Any?> pass value

2019-07-26 08:37发布

问题:

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
    }
}

回答1:

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.



标签: kotlin