gpt4 book ai didi

java - 为什么在 Kotlin 中可以在 DayForecast(HashMap(it)) 之前插入一行代码?

转载 作者:行者123 更新时间:2023-11-30 06:26:10 24 4
gpt4 key购买 nike

我正在 Kotlin for Android Developers(本书)学习有关 Anko 的示例代码,网址为 https://github.com/antoniolg/Kotlin-for-Android-Developers

我添加一行var myMap=it之前DayForecast(HashMap(it)) ,我认为App会崩溃,因为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)
})

最佳答案

该函数的签名是 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)

关于java - 为什么在 Kotlin 中可以在 DayForecast(HashMap(it)) 之前插入一行代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47160136/

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