gpt4 book ai didi

android - 为什么我在 Kotlin 中使用原始的 parseList 函数时得不到正确的结果?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:12:07 25 4
gpt4 key购买 nike

我正在为 Android 开发人员学习 Kotlin 中关于 Anko 的示例代码(书籍)https://github.com/antoniolg/Kotlin-for-Android-Developers

方法一来自样例代码,重写了parseList,但是比较难理解。

所以我尝试使用方法2而不是方法1,方法2使用原始的parseList函数,但是当我使用方法2时我得到的是空白记录,我在方法2中犯了什么错误

class DayForecast(var map: MutableMap<String, Any?>) {
var _id: Long by map
var date: Long by map
var description: String by map
var high: Int by map
var low: Int by map
var iconUrl: String by map
var cityId: Long by map

constructor(date: Long, description: String, high: Int, low: Int,
iconUrl: String, cityId: Long) : this(HashMap()) {
this.date = date
this.description = description
this.high = high
this.low = low
this.iconUrl = iconUrl
this.cityId = cityId
}
}

方法一

override fun requestForecastByZipCode(zipCode: Long, date: Long) =
forecastDbHelper.use {
val dailyRequest = "${DayForecastTable.CITY_ID} = ? AND ${DayForecastTable.DATE} >= ?"
val dailyForecast = select(DayForecastTable.NAME)
.whereSimple(dailyRequest, zipCode.toString(), date.toString())
.parseList { DayForecast(HashMap(it)) }
/* common code block */
}

fun <T : Any> SelectQueryBuilder.parseList(parser: (Map<String, Any?>) -> T):
List<T> = parseList(object : MapRowParser<T> {
override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
})

方法二

override fun requestForecastByZipCode(zipCode: Long, date: Long) = 
forecastDbHelper.use {
val dailyRequest = "${DayForecastTable.CITY_ID} = ? AND ${DayForecastTable.DATE} >= ?"
val dailyForecast = select(DayForecastTable.NAME)
.whereSimple(dailyRequest, zipCode.toString(), date.toString())
.exec { parseList(classParser<DayForecast>()) }
/* common code block */
}

最佳答案

我真的认为您应该坚持使用“方法 1”方法,一旦您意识到 Kotlin 允许您做什么,它就会容易得多。由于我不知道您对 Kotlin 了解多少,因此我会尽量全面介绍这一点。

现有类SelectQueryBuilder有(我想)一个叫做 parseList 的函数, 现有函数采用 MapRowParser<T> . MapRowParser<T>有一个函数 parseRow这需要 Map<String, Any?>并返回 T .

在旧的 Java 工作方式中,您将派生自 MapRowParser<T>并会覆盖 parseRow以便它进行您想要的转换;转换 Map<String, Any?>进入 DayForecast (通用 T 现在有一个类型)。此派生类的一个实例被传递到现有的 parseList功能。您的派生类看起来像

class MapToDayForecastRowParser extends MapRowParser<DayForecast> {
@Override public DayForecast parseRow(Map<String, Object> map) {
// Note that Java's "Object" is more or less Kotlin's "Any?"
return new DayForecast(map); // Might need to convert the map type btw
}
}

扩展方法使得包装/隐藏/抽象派生类的创建变得非常容易。扩展方法采用 lambda,也就是说,您必须解析为新的 parseList。方法采用 Map<String, Any?> 的代码块并返回 T (这就是 DayForecast(HashMap(it)) 正在做的,it 是一个自动命名的变量,即 Map 。扩展方法然后调用现有的 parseList 方法,在它自己创建的匿名类中进行解析。这意味着曾经使用此扩展方法创建一个新的匿名类,但 Kotlin 编译器处理得很好。

一开始让我感到困惑的一个部分是 Kotlin 处理匿名类的方式。

// Java
new MapRowParser<T>() {
@Override public T parseRow(Map<String, Object>) {
/* Map to T logic */
}
}
// Kotlin
object : MapRowParser<T> {
override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
}

Kotlin 还使处理“lambda”变得非常容易。它被解析为扩展方法 parser然后设置为我们匿名类的实现 parseRow功能。如果你愿意,你也可以重用它们,所以如果你需要在很多地方做同样的解析,你可以使用命名函数。

这种新的 Kotlin 方式的巨大优势在于它可以很容易地专注于您想要做的事情。使用该扩展方法,可以非常快速地重新使用它,以便在另一个查询中您可以执行 parseList{ it.getOrDefault("name", "unkown_user") } .您现在可以轻松地思考“如果每一行都是一个 map ,我如何将其转换为我想要的值?”。

关于android - 为什么我在 Kotlin 中使用原始的 parseList 函数时得不到正确的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47091897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com