看 kotlin 代码的时候,经常有个疑惑就是明明是个函数后面为什么不是 ()
而是 {}
。百度搜索很久不知道该搜索什么东西,最后找到了这篇文章:https://zhuanlan.zhihu.com/p/78571521 。下面是其中一段摘录,解释了其中的奥秘。
Lambda 表达式的语法
{x: Int, y: Int -> x + y}
可以把 lambda 表达式存储在一个变量中,把这个变量当做普通函数对待:
val sum = {x: Int, y: Int -> x + y}
println(sum(1, 2))
也可以直接调用 lambda 表达式:
{ println(42) }()
但这样语法毫无可读性,也没意义,如果确定需要把一小段代码封闭在一个代码块中,可以使用库函数 run 来执行传给它的 lambda:
run{ println(42) }
因此,上述的 maxBy 函数在不用简明语法的情况下可这么写:
people.maxBy({ p: Person -> p.age} )
Kotlin 有这样的一个约定:如果 lambda 表达式是函数调用的最后一个实参,它可以放到括号的外边。
people.maxBy(){ p: Person -> p.age}
当 lambda 是函数唯一实参时,还可以去掉代码中的空括号对:
people.maxBy{ p: Person -> p.age}
如果 lambda 参数的类型可以被推导出来,你就不需要显示地指定它:
people.maxBy{ p -> p.age}
可使用默认参数名称 it 命名参数。如果当前上下文期望的是只有一个参数的 lambda 且这个参数的类型可以推导出来,就会生成这个名称:
people.maxBy{ it.age}
如果使用变量存储 lambda,那么久没有可以推断出参数类型的上下文,所以你必须显示地指定参数类型:
val getAge = {p: Person -> p.age}
people.maxBy(getAge)
此外,如果 lambda 表达式由多个语句构成,那么最后一个表达式就是 lambda 的结果:
val sum = { x: Int, y: Int ->
println("Computing the sum of $x and $y...")
x + y
}
println(sum(1, 2))