我在https://github.com/antoniolg/Kotlin-for-Android-Developers
了解了针对Android开发者的Kotlin的Anko示例代码(该书)我在var myMap=it
之前添加一行DayForecast(HashMap(it))
,我认为应用程序会崩溃,因为parseList的定义是parseList(parser: (Map<String, Any?>) -> T)
,我只能为parseList指定一个功能。但是应用程序可以正常运行,为什么?
我修改过的ForecastDb.kt
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 {
var myMap=it
DayForecast(HashMap(it))
}
}
ForecastDb.kt
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)) }
}
DatabaseExtensions.kt
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)
})
答案 0 :(得分:1)
该功能的签名是parseList(parser: (Map<String, Any?>) -> T)
。 (Map<String, Any?>) -> T)
作为参数意味着parseList
函数将一个函数类型作为参数,该函数类型具有返回Map<String, Any?>
的单个参数(T
)的签名。
这是higher-order functions)的一个例子。
在您的示例中,您传递的是lambda expression:
.parseList {
var myMap=it
DayForecast(HashMap(it))
}
在lambda表达式中,只要返回类型T
,就可以执行任何操作。只要在结尾返回类型T
,就可以调用多个函数,创建对象,分配变量等等。
为了进一步说明这个想象,我们有一个函数将另一个函数作为参数,它将Int
作为参数并返回Int
:
fun funTakingOne(function: (Int) -> Int): Int {
return function(1)
}
现在,调用该函数的一种方法是传入一个lambda表达式:
val output = funTakingOne {
it + 5
}
println(output)
此处的输出为6
。
您还可以使用qualified return syntax显式返回lambda中的值。以下是两个相同的电话:
funTakingOne {
it + 2
}
funTakingOne {
return@funTakingOne it + 2
}
此lambda表达式的返回值为Int
。我们也可以在lambda表达式中做其他事情,只要输出是Int
:
funTakingOne {
val someCalculation: Int = expensiveCalculation(it)
val otherCalculation: Int = otherCalculation(it)
someCalculation / otherCalculation
}
如果您尝试在此处返回Int
以外的任何内容,编译器将因类型不匹配而失败:
// This fails to compile
funTakingOne {
"oh no, I fail"
}
在您的示例中,签名具有generic参数(类型T
)。它与上面的示例类似,只是函数必须返回T
类型的东西。
这是另一个人为的例子。将函数作为参数的函数,该函数具有单个String
参数并返回类型为T
的内容:
fun <T> funReturnT(function: (String) -> T): T {
return function("Hello World")
}
调用它可能如下所示:
val output = funReturnT {
"$it! Great day today!"
}
println(output)
此处的输出为Hello World! Great day today!
。这里推断的output
类型是String
,因为我们的lambda表达式返回String
(函数的推断类型T
)。这与执行以下操作相同:
val output: String = funReturnT {
"$it! Great day today!"
}
println(output)
如果我们更改output
的预期类型,我们将因类型不匹配而导致编译器失败。
// This fails to compile
val output: Int = funReturnT {
"$it! Great day today!"
}
println(output)