以下代码来自“ 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())
}
答案 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)
不,您实际上不需要扩展功能。如果您经常调用insert
方法(或其他任何需要数组而不是Map
的方法),则应该有适当的位置。但是,根据您更经常调用的内容,您可能宁愿使用Map
作为参数为特定方法提供扩展功能。
如果您不希望使用扩展功能,则可以直接调用以下命令(如果您有铅地图):
*map.map { it.key to it.value }.toTypedArray()
我想知道为什么作者允许Any?
类上的CityForecast
作为值,然后决定使用value!!
。我宁愿建议您使用Any
,那样就不允许使用null
值,否则建议使用默认值,例如value?:""
。请注意,如果使用Any
,则可能需要确保数据库中的数据不包含任何null
值(使用NOT NULL
约束创建的列)。
您真的应该尝试一下。如果崩溃,您将熟悉如何处理错误。我假设如果您在地图中使用NullPointerException
值并保留提及的扩展功能,则它会崩溃(或至少在某个位置抛出null
;-)),因为value!!
调用将失败。请注意:您总是可以在这里提出新问题,如果有您无法解决的问题,或者找不到任何好的信息来源。