如何将lambda表达式放在mapTo上的参数之后调用合法语法?

Alt*_*yyr 15 lambda kotlin

我发现了一段我不理解的代码.

我正在JSONArray变成一个List.
Kotlin提供了mapTo它的功能stdlib(链接)

mapTo

inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(
    destination: C, 
    transform: (T) -> R
): C (source)
Run Code Online (Sandbox Code Playgroud)

将给定的转换函数应用于原始集合的每个元素,并将结果附加到给定目标.

这个函数有2个参数,可以像这样使用(如预期的那样):

(0..jsonArray.length() - 1).mapTo(targetList, {it -> jsonArray[it].toString()})
Run Code Online (Sandbox Code Playgroud)

但显然这也是有效的语法(不是预期的):

(0..jsonArray.length()-1).mapTo(targetList) {it -> jsonArray[it].toString()}
Run Code Online (Sandbox Code Playgroud)

如您所见,函数参数结束后outputList,lambda表达式只是放在函数调用的末尾.


此外,这是合法的(如预期):

val transformation = {it : Int -> jsonArray[it].toString()}
(0..jsonArray.length()-1).mapTo(targetList, transformation)
Run Code Online (Sandbox Code Playgroud)

但这不是(???):

val transformation = {it : Int -> jsonArray[it].toString()}
(0..jsonArray.length()-1).mapTo(targetList) transformation
Run Code Online (Sandbox Code Playgroud)

mie*_*sol 22

文档所述:

在Kotlin中,有一个约定,如果函数的最后一个参数是一个函数,并且您将lambda表达式作为相应的参数传递,则可以在括号外指定它:

lock (lock) {
    sharedResource.operation()
}
Run Code Online (Sandbox Code Playgroud)

高阶函数的另一个例子是map():

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
}
Run Code Online (Sandbox Code Playgroud)

可以按如下方式调用此函数:

val doubled = ints.map { it -> it * 2 }
Run Code Online (Sandbox Code Playgroud)

请注意,如果lambda是该调用的唯一参数,则可以完全省略调用中的括号.

文档明确指出,为了使上述工作,最后一个参数必须是lambda表达式而不是匹配类型的变量.

  • 这次大会背后的原因是什么? (6认同)
  • 为什么Android Studio IDE希望您做得这么糟糕? (2认同)