- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在为 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/
我正在查看Kotlin Github page我注意到 Kotlin 语言本身大部分是用 Kotlin 编写的:我只是想知道,一种语言怎么可能大部分都是用它自己的语言编写的?在您可以使用正在创建的语言
我有以下非常简单的 kotlin 代码来演示中缀函数 com.lopushen.demo.presentation 包 fun main(args: Array) { print("Hello
我在 Java 中有 2 个模型类,其中一个扩展了另一个 @UseStag public class GenericMessages extends NavigationLocalizationMap
Kotlin 代码 runBlocking { flow { for (i in 0..4) { println("Emit $i")
这三个 Kotlin 插件和它们的实际作用有什么区别? plugins { id 'kotlin-android' id 'org.jetbrains.kotlin.android'
我正在为某些现有库添加 Kotlin 原生 linuxX64 目标支持。库已成功编译,但在运行测试用例时,出现以下运行时错误: kotlin.native.concurrent.InvalidMuta
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 2 年前。 Improve t
我创建了一个类并向其添加了一个与成员函数具有相同签名的扩展,并执行了这个方法,它总是执行成员方法。 class Worker { fun work() = "...working" } fun
我知道传递给函数的参数将被视为“val”,即使变量被初始化为“var”。但这对我来说一直是个问题。在下面的示例代码中,我想通过使用函数“changeNum”修改变量“num”的值。但当然,Kotlin
现在,我正在尝试用 Kotlin 重写我的 Java 应用程序。然后,我遇到了日志语句,比如 log.info("do the print thing for {}", arg); 所以我有两种方法可
有点出名article关于许多语言的异步编程模型的状态,指出它们存在“颜色”问题,特别是将生态系统分为两个独立的世界:异步和非异步。以下是这种语言的属性: 每个函数都有一种颜色,红色或蓝色(例如asy
因为 KDoc 文档生成引擎是 abandoned in favor of Dokka , Kotlin 文档应该称为“KDoc 注释”,还是“Dokka 注释”? 最佳答案 如所述here , KD
我想在可空对象上传递函数引用。以 Android 为例,假设我想使用 Activity#onBackPressed来自作为该事件的子级的片段。 如果我想调用这个函数,我可以很容易地做到 activit
我有一个列表 (x, y)其中y只能是 0 或 1 这样 例如: [(3, 0), (3, 1), (5, 1)] [(5, 0), (3, 1), (5, 1)] [(1, 1), (3, 1),
从强类型语言的定义来看: A strongly-typed programming language is one in which each type of data (such as intege
这不能编译的事实是否意味着它们不是一流的类型? fun foo(s: String): Int = s.length // This won't compile. val bar = foo 有没有办
如果在 Java i++是一个表达式和 i++;是一个表达式语句,分号(;) 在 Kotlin 中是可选的,是 i++ Kotlin 中的表达式或表达式语句? 最佳答案 i++是一个表达式,因为它有一
代码(如下所示)是否正确?它取自 Kotlin-docs.pdf 的第 63 页,这也是 https://kotlinlang.org/docs/reference/generics.html 的最后
我正在尝试使用 Kotlin 为 Android 的一些全局 API 解析器(检查网络连接、调用 API 并通过来自源的单个调用返回格式化数据),并且在某些时候我不得不创建一个通用类型 object就
kotlinlang 中的任务: 使用月份变量重写此模式,使其与格式 13 JUN 1992(两位数字、一个空格、一个月份缩写、一个空格、四位数字)中的日期相匹配。 答案是:val month = "
我是一名优秀的程序员,十分优秀!