在 Java 里,不允许把方法作为参数传递
在 Kotlin 里,函数的参数和返回值可以是函数类型 此类函数被称为高阶函数
fun a(funParam: (Int) -> String): (Int) -> Unit { }
对于一个已经声明好的函数,不管是作为函数的参数传递还是赋值给变量都需要在函数名左边加上双冒号(::) , 如:a(::b) val d = ::b
在一个函数名的左边加了双冒号,它就不表示这个函数本身了,而表示一个对象,或者说一个指向对象的引用,但这个对象不是函数本身,而是一个和这个函数具有相同功能的对象
使用方法:val d = ::b b(1) d(1) (::b)(1)
实际上,对一个函数类型的对象加括号、加参数,它真正调用的是这个对象的invoke()函数。所以,可以对一个函数类型的对象调用invoke()方法,但不能对一个函数这么做
要传一个函数类型的参数或者把一个函数类型的对象赋值给变量,除了用双冒号来拿现成的函数使用,还可以直接把这个函数挪过来写,这种写法叫做匿名函数
如果Lambda是函数的最后一个参数,可以把 lambda 写在括号的外面;而如果 lambda 是函数唯一的参数,还可以直接把括号去掉
如果要把一个匿名函数赋值给变量,如果也简写成 Lambda 的形式,就不能省略掉 Lambda 的参数类型。如果非要省略,就必须给变量指明类型
lambda 的返回值不是用 return 来返回,而是取最后一行代码的值
lambda 不用写也不能写返回值类型
val d = { param: Int ->
doSomething()
}
Java 从8开始引入了对 lambda 的支持,对于单抽象方法的接口,简称SAM接口,Java8允许用 Lambda 表达式来创建匿名类对象,但它本质上还是在创建一个匿名类对象
Kotlin 的 lambda 跟 Java 8 本质上是不同的,Kotlin的 lambda 是实实在在的函数类型的对象
Kotlin不支持用 lambda 表达式来简写匿名类对象,不过当和Java交互的时候,Kotlin是支持这种写法的。当函数参数是 Java 的单抽象方法的接口时,依然可以使用 lambda 来写参数。这并不是 Kotlin 增加了功能,而是对于来自Java的SAM接口,Kotlin 会为它们额外创建一个把参数替换为函数类型的桥接方法,让你可以间接的创建Java的匿名类对象