首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我可以在Kotlin的DayForecast(HashMap(it))前面插入一行代码?

为什么我可以在Kotlin的DayForecast(HashMap(it))前面插入一行代码?
EN

Stack Overflow用户
提问于 2017-11-07 14:16:58
回答 1查看 64关注 0票数 1

我正在学习https://github.com/antoniolg/Kotlin-for-Android-Developers的安卓开发者在Kotlin的Anko示例代码(这本书)

我在var myMap=it之前添加了一行DayForecast(HashMap(it)),我认为应用程序会崩溃,因为parseList的定义是parseList(parser: (Map<String, Any?>) -> T),我只能给应用程序正确运行的parseList.But分配一个函数,为什么?

My改良的ForecastDb.kt

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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)
})
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-07 14:24:10

函数的签名是parseList(parser: (Map<String, Any?>) -> T)(Map<String, Any?>) -> T)作为参数意味着parseList函数以带有单个参数(Map<String, Any?>)签名的函数类型作为参数,该参数返回T

这是https://kotlinlang.org/docs/reference/lambdas.html的一个例子)。

在您的示例中,您正在传递一个https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions

代码语言:javascript
复制
.parseList { 
   var myMap=it
   DayForecast(HashMap(it)) 
}

在lambda表达式中,只要返回T类型,就可以执行任何操作。只要在末尾返回T类型,就可以调用多个函数、创建对象、分配变量等等。

为了进一步说明这一点,假设我们有一个函数,它以另一个函数作为参数,以一个Int作为参数,并返回一个Int

代码语言:javascript
复制
fun funTakingOne(function: (Int) -> Int): Int {
  return function(1)
}

现在,调用该函数的一种方法是传入lambda表达式:

代码语言:javascript
复制
val output = funTakingOne { 
  it + 5
}
println(output)

这里的输出是6

您还可以使用https://kotlinlang.org/docs/reference/returns.html#return-at-labels显式地从lambda返回一个值。以下是两个相同的电话:

代码语言:javascript
复制
funTakingOne { 
  it + 2 
}
funTakingOne { 
  return@funTakingOne it + 2
}

这个lambda表达式的返回是一个Int。我们还可以在lambda表达式中执行其他操作,只要输出是Int

代码语言:javascript
复制
funTakingOne {
  val someCalculation: Int = expensiveCalculation(it)
  val otherCalculation: Int = otherCalculation(it)
  someCalculation / otherCalculation
}

如果在这里尝试返回Int以外的任何内容,编译器将因类型不匹配而失败:

代码语言:javascript
复制
// This fails to compile
funTakingOne {
  "oh no, I fail"
}

在您的示例中,签名有一个通用参数(T类型)。它与上面的示例类似,只是函数必须返回T类型的内容。

这是另一个人为的例子。一个函数,它以函数为参数,具有单个String参数,并返回某种类型的T

代码语言:javascript
复制
fun <T> funReturnT(function: (String) -> T): T {
  return function("Hello World")
}

调用它可能如下所示:

代码语言:javascript
复制
val output = funReturnT {
  "$it! Great day today!"
}
println(output)

这里的输出是Hello World! Great day today!。这里推断的output类型是String,因为我们的lambda表达式正在返回String (函数的推断类型T )。这与执行以下操作相同:

代码语言:javascript
复制
val output: String = funReturnT {
  "$it! Great day today!"
}
println(output)

如果我们更改了output的预期类型,就会因为类型错配而导致编译器失败。

代码语言:javascript
复制
// This fails to compile
val output: Int = funReturnT {
  "$it! Great day today!"
}
println(output)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47160136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档