首发于公众号: DSGtalk1989
19.高阶函数与 lambda 表达式
我们通常将函数作为参数或者返回值的函数成为高阶函数
-
带接收者的函数类型
在kotlin中我们,函数也是一种类型。比如
() -> Int
,这个表示无参的返回类型为整型的函数。(String, Int) -> Int
表示需要两个参数String
和Int
,并且返回的Int
的函数。这里要介绍的是带接收者的函数类型,比如
String.(String) -> Int
,其实也是需要两个参数,但是这样表达的好处是这个方法可以被当做拓展函数来使用。val stringPlus: String.(String) -> String = String::plus fun main() { stringPlus("1", "2") "1".stringPlus("2") }
我们即可以直接传两个
String
到这个方法中去,也可以当成拓展函数来直接调用String
的stringPlus
方法,并且往里面传一个字符串。也就是
String.(String)
可以当成(String,String)
来使用,而反过来则不行哦。
-
invoke方法
invoke
关键字跟在方法名后面,表示调用该方法,跟不加的效果是一样的,同上的例子println(stringPlus.invoke("<-", "->")) println(stringPlus("Hello, ", "world!"))
invoke
关键字还会用在类或者接口内的方法定义中class AA { companion object Factory { operator fun invoke (xxx: Any) = xxx fun test11(){} } operator fun invoke(dda : String) = "22" fun test(){ } }
我们在两个地方使用到了
invoke
,注意,我们直接通过操作符重载的方式可以定义类本身的构造方法。比如上面的伴生对象的
invoke
方法,就是重载了伴生对象的构造方法,即直接调用AA(xxx: Any)
可以获得一个Any
对象。或者我们走一个更加容易理解的方式,就是所有重载的
invoke
操作符,我们都可以通过对象.invoke(参数)
的方式去调用,由于invoke
又是可以省略的,所以我们可以直接通过对象(参数)
的方式去调用//伴生对象(参数)直接使用 val aaa: Any = AA(6) val aa: Unit = AA.test11() val bbb = AA() bbb.test() bbb.invoke("1") //对象(参数) bbb("1")
-
lambda中it的出现时机
我们在前面讲过,通常高阶函数的定义和调用方式如下
fun html( a : (String, Int, Short) -> String){ } html { s, i, sh -> "test" }
由于高阶函数最后一个参数是函数,所以可以直接写在方法外,又由于只有一个函数参数,所以连括号都可以省去了。
其次,我们传入函数的方式是,大括号,并且包括所有的参数自定义(一般为类型的大写字母,比如
String
就是s
,Int
就是i
,Short
就是sh
)加上->
然后是函数体。kotlin中将高阶函数中的函数参数只有一个传参的情况简略了我们自己去写
s ->
的过程,直接帮我们生成了it ->
,即fun html( a : (String) -> String){ } html { s -> s + "test" } //等价 html { it + "test" }
-
函数参数的自动识别
kotlin可以自动进行推断函数体,比如,我们需要传入高阶函数的函数体是
(Int) -> Int
,那么如果有什么方法本身也是这种类型的,直接传入改方法即可。fun html( a : (String) -> String){ } fun testString(a : String): String{ return a } fun main(){ html { testString("1") } }
-
高阶函数没有使用到函数参数
我们上面举的例子中都没有使用到具体的方法参数,即
html
中我们并没有去使用a
,这样的话在编译的过程中,传入的方法将不会被编译。即上文中的
testString
方法将完全不会被编译到main
方法中高阶函数我们一般的使用方法都是在方法中调用方法,直接调用方法的方式如下
fun html( a : (String) -> String){ a.invoke("hello") a("hello") }
否则高阶函数将变得没有意义。
Kotlin学习笔记之 13 基础操作符run、with、let、also、apply