引子 function-literals-with-receiver-in-kotlin
在 kotlin 中函数也是一个变量类型,可以定义变量,定义参数。lambda 也是函数,在使用的时候发现有时候申明的方式却有点不同。比如在kotlin 中有两个预定义的方法apply()
和also()
。
1 | public inline fun <T> T.also(block: (T) -> Unit): T { |
1 | public inline fun <T> T.apply(block: T.() -> Unit): T { |
首先这两个函数都为T
类型做了扩展函数申明,只不过传递的参数不一样。
参数一个是block: (T) -> Unit
,一个是T.() -> Unit
。
第一个很好理解就是定义了一个lambda 函数,这个lambda函数类型是,需要传递一个参数T
,并且返回空的函数。在调用的时候需要使用it
修饰符来访问T
类型的变量以及方法
第二个的作用其实跟第一个是一样的,也是传递参数T
,只不过写法不一样。传递的是一个T
类型的扩展函数。在调用的时候使用this
修饰符,或者干脆就不要修饰符来访问T
类型的变量或者函数。
在 lambda 函数体内可以不使用修饰符访问对象的其他属性
下面就是两者的写法区别。
1 | val rect1 =Rect().also { |
在需要向lambda传递参数的时候两者是可以互换的,只不过写法不一样。
带与不带接收者的函数类型非字面值可以互换,其中接收者可以替代第一个参数,反之亦然。例如,(A, B) -> C 类型的值可以传给或赋值给期待 A.(B) -> C 的地方,反之亦然:
1 | val repeatFun: String.(Int) -> String = { times -> this.repeat(times) } |
参考:
kotlin-lambdas
Understanding a parameter that is initialized as an extension function