如何将MutableMap <string,any?=“”>转换为vararg值:Pair <string,any?=“”>?

时间:2018-07-22 01:59:41

标签: android kotlin anko

以下代码来自“ Android开发人员的Kotlin”,您可以在https://github.com/antoniolg/Kotlin-for-Android-Developers上访问它

为了将行数据插入CityForecastTable.NAME,我必须通过源代码 vararg

传递fun SQLiteDatabase.insert

1:作者扩展了toVarargArray(),将MutableMap<String, Any?>转换为Pair<String, Any?>,我不知道是否有更好的方法那。我需要使用扩展功能吗?

2 :作者必须使用代码C中的代码it.value!!,我不知道代码fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V?>> = map({ Pair(it.key, it.value) }).toTypedArray()是否正确?

3 :我不知道插入行包含空值的行数据时应用是否会崩溃。

import org.jetbrains.anko.db.*
class ForecastDb(private val forecastDbHelper: ForecastDbHelper = ForecastDbHelper.instance,
                 private val dataMapper: DbDataMapper = DbDataMapper()) : ForecastDataSource {

    fun saveForecast(forecast: ForecastList) = forecastDbHelper.use {           

         //dataMapper.convertFromDomain(forecast) will return CityForecast object 
         with(dataMapper.convertFromDomain(forecast)) {
            insert(CityForecastTable.NAME, *map.toVarargArray())           
        }
    }

}


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

代码C

fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V>> =
        map({ Pair(it.key, it.value!!) }).toTypedArray()

源代码

fun SQLiteDatabase.insert(tableName: String, vararg values: Pair<String, Any?>): Long {
    return insert(tableName, null, values.toContentValues())
}

2 个答案:

答案 0 :(得分:3)

那里几乎所有东西

使用星号*运算符(也称为扩展运算符)将数组扩展到函数内部的vararg

https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs

添加?达到该值,您就可以开始使用

fun <K, V : Any> Map<K, V?>.toVarargArray() = map { it.key to it.value }.toTypedArray()

    insert("", *mapOf("k" to "v").toVarargArray())

答案 1 :(得分:1)

  1. 不,您实际上不需要扩展功能。如果您经常调用insert方法(或其他任何需要数组而不是Map的方法),则应该有适当的位置。但是,根据您更经常调用的内容,您可能宁愿使用Map作为参数为特定方法提供扩展功能。

    如果您不希望使用扩展功能,则可以直接调用以下命令(如果您有铅地图):

    *map.map { it.key to it.value }.toTypedArray()
    
  2. 我想知道为什么作者允许Any?类上的CityForecast作为值,然后决定使用value!!。我宁愿建议您使用Any,那样就不允许使用null值,否则建议使用默认值,例如value?:""。请注意,如果使用Any,则可能需要确保数据库中的数据不包含任何null值(使用NOT NULL约束创建的列)。

    < / li>
  3. 您真的应该尝试一下。如果崩溃,您将熟悉如何处理错误。我假设如果您在地图中使用NullPointerException值并保留提及的扩展功能,则它会崩溃(或至少在某个位置抛出null ;-)),因为value!!调用将失败。请注意:您总是可以在这里提出新问题,如果有您无法解决的问题,或者找不到任何好的信息来源。