当代码HashMap(it)运行时发生了什么?

以下示例代码来自Kotlin for Android开发人员, 网址为https://github.com/antoniolg/Kotlin-for-Android-Developers/blob/master/app/src/main/java/com/antonioleiva/weatherapp/数据/分贝/ ForecastDb.kt

我无法完全理解代码DayForecast(HashMap(it)) 。 这是什么意思?

而且,当执行parseList { DayForecast(HashMap(it)) }时发生了什么?

 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)) } } 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 } } 

添加

在下面的示例代码中,我可以在代码中理解“it” val doubled = ints.map {it * 2 } ,“it”是var ints的元素,比如10,20,30!

但在代码val dailyForecast = select(DayForecastTable.NAME).whereSimple(dailyRequest, zipCode.toString(), date.toString()).parseList { DayForecast(HashMap(it)) } ,它是什么意思?

示例代码

  var ints= listOf(10,20,30); val doubled = ints.map {it * 2 } fun <T, R> List<T>.map(transform: (T) -> R): List<R> { val result = arrayListOf<R>() for (item in this) result.add(transform(item)) return result } 

正如Lym Zoy所说, it是封闭的单一参数的隐含名称。

如果您不熟悉Kotlin中的闭包和高阶函数,可以在这里阅读。 采用闭包/函数/拉姆达的函数,基本上是要求一些帮助来完成它的工作。

我喜欢用sortedBy作为一个很好的例子。 sortedBy是Kotlin集合库中的一个函数,它将对集合进行排序,但为了使其工作,每个项目都需要一个可比较的属性。 它解决这个问题的方法是,请求你,sortedBy函数的用户,提供一个函数,该函数接受集合的成员并返回一个可比较的属性。 例如,如果集合是一个Person对象列表,如果您想按firstName,lastName或age排序,则可sortedBy提供一个不同的闭包。

下面是一个快速示例,您可以在这里找到它,它显示了sortedBy如何取得一个闭包参数,该参数带有一个成员并返回一个可比较的属性, sortedBy可以使用这个属性来排列集合中的各个成员。 在第一种情况下,闭包/函数返回成员的年龄,在第二种情况下,闭包返回lastName(使用隐式形式),两者都是Comparable,一个Int和一个String。

 data class Person(val firstName: String, val lastName: String, val age: Int) fun main(args: Array<String>) { val people = listOf( Person("Jane", "Jones", 27), Person("Johm", "Smith", 22), Person("John", "Jones", 29)) val byAge = people.sortedBy { person -> person.age } // explicit argument: person is a memeber of the List of Persons val byLastName = people.sortedBy { it.lastName } // implict argument: "it" is also a member of the List of Persons println(people) println(byAge) println(byLastName) 

}

回到你的具体问题的细节。

在你的问题中,在这里找到的parseList函数是这样定义的:

 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) }) 

这是一个函数,它需要一个闭包,它需要一个Map<String, Any?>类型的参数

所以在你的问题中显示的电话:

 .parseList { DayForecast(HashMap(it)) } 

其中{ DayForecast(HashMap(it)) }是期望传递给parseList的闭包,
也可以使用更长的形式{ arg -> DayForecast(HashMap(arg) } ,但是短格式{ DayForecast(HashMap(it)) }是更为惯用的形式,使用it作为参数可以跳过arg ->部分。

所以在这种情况下, it是由parseList函数提供的一个Map对象。 然后把it引用的对象作为唯一参数传递给HashMap的构造函数(这并不意外地期望Map),然后将构造的结果传递给DayForecast的构造DayForecast

是单个参数的隐式名称。 在这里检查文档。