Kotlin中Lambda作为尾随参数传递的报错原因及相关疑问
第一段代码
错误原因
resultAdd2里的Lambda写法{ (x, y) -> x + y }中,(x, y)是解构声明,它会让Kotlin认为这个Lambda只接收单个参数,然后把这个参数解构为x和y两个变量。但calculate函数要求的operation参数是(Int, Int) -> Int类型——也就是需要接收两个独立Int参数的函数,两者类型不匹配,因此编译器报错。
正确写法要去掉参数外的括号,写成{ x, y -> x + y },这样Lambda就明确接收两个Int参数,和函数要求的类型一致。
疑问解答
大括号里的代码是Lambda表达式,属于匿名函数的简化形式,本质是函数类型的实例。calculate(5, 3) { x, y -> x + y }确实是把这个Lambda作为参数传入calculate函数:因为calculate的最后一个参数是函数类型,所以可以用Kotlin的尾随Lambda语法把Lambda放在括号外面,等价于calculate(5, 3, { x, y -> x + y })。
第二段代码
错误原因
greet函数要求的action参数是() -> Unit类型——也就是无参数的函数。错误写法里的{ () -> println("Hello, World!") }出现了语法误解:这里的()被Kotlin当成了一个参数的合法标识符,导致这个Lambda被推断为(Any?) -> Unit(接收任意类型的单个参数),和期望的无参数函数类型不匹配,因此报错。
正确的无参数Lambda写法有两种:要么直接省略参数列表,写成{ println("Hello, World!") };如果要显式标注无参数,应该写成{ -> println("Hello, World!") }(只保留->,前面不写参数)。
内容的提问来源于stack exchange,提问作者Thành Nguyễn Chi

