Kotlin带有接收者函数类型(block:T.()->Unit)
前⾔
Kotlin标准库的 Standard.kt 包含⼏个函数,其唯⼀⽬的是在对象上下⽂内执⾏代码块。 当我们在提供了lambda表达式的对象上调⽤此类函数时,它将形成⼀个临时作⽤域。在此作⽤域中,我们可以访问没有其名称的对象,这些功能称为作⽤域函数。
t-ara成员左乳曝光⽐如我们经常使⽤的 apply 和 also 函数:
public inline fun<T> T.apply(block: T.()-> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
public inline fun<T> T.also(block:(T)-> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
如果我们仔细⽐较这两个扩展函数会发现它们⾮常相似:它们都接收⼀个 block 函数并返回 this 值。
唯⼀的差别就在于 apply 的 block 函数类型为:T.() -> Unit ,⽽ also 的 block 函数类型为:(T) -> Unit) 。
那么这两种函数类型到底差别在哪⾥呢 ?
T.() -> Unit和(T) -> Unit)
⾸先我们看下
class Test {
fun main(block: Int.()-> Unit){
val also: Class<Test>= javaClass.also{
val canonicalName = it.canonicalName
println(canonicalName)
}
val apply: Class<Test>= javaClass.apply{
println(canonicalName)
}
}
}
这样看起来不太明显,我们看下AndroidStudio的智能提⽰:
这样看起来是不是简单多了,在 also ⽅法中接收到的是 it , ⽽在 apply ⽅法中接收到的是 this ,⽽表达式 it.canonicalName 和canonicalName 的差别不⽤我说了吧。
apply 以 this 值作为接收者调⽤指定的函数[block],并返回 this 值。
⽽ also 以 this 值作为参数调⽤指定的函数[block],并返回 this 值。
参数我们都理解,但是接收者是个什么概念,貌似从来没听过?
Kotlin的函数类型
Kotlin 使⽤类似 (Int) -> String 的⼀系列函数类型来处理函数的声明:val onClick: () -> Unit = ……。
这些类型具有与函数签名相对应的特殊表⽰法,即它们的参数和返回值:
所有函数类型都有⼀个圆括号括起来的参数类型列表以及⼀个返回类型:(A, B) -> C 表⽰接受类型分别为 A 与 B 两个参数并返回⼀个
C 类型值的函数类型。 参数类型列表可以为空,如 () -> A。Unit 返回类型不可省略。王自健前妻照片
郑元畅林依晨函数类型可以有⼀个额外的接收者类型,它在表⽰法中的点之前指定类型: A.(B) -> C 表⽰可以在 A 的接收者对象上以⼀个 B 类型参数来调⽤并返回⼀个 C 类型值的函数。 带有接收者的函数字⾯值通常与这些类型⼀起使⽤。
挂起函数属于特殊种类的函数类型,它的表⽰法中有⼀个 suspend 修饰符 ,例如 suspend () -> Unit 或者 suspend A.(B) -> C 。
函数类型表⽰法可以选择性地包含函数的参数名:(x: Int, y: Int) -> Point。 这些名称可⽤于表明参数的含义。
带有接收者的函数类型
带有接收者的函数类型,例如 A.(B) -> C,可以⽤特殊形式的函数字⾯值实例化—— 带有接收者的函数字⾯值。
Kotlin 提供了调⽤带有接收者(提供接收者对象)的函数类型实例的能⼒。
在这样的函数字⾯值内部,传给调⽤的接收者对象成为隐式的 this,以便访问接收者对象的成员⽽⽆需任何额外的限定符,亦可使⽤ this 表达式 访问接收者对象。
这种⾏为与扩展函数类似,扩展函数也允许在函数体内部访问接收者对象的成员。
淘宝企业店铺是什么意思
为了表⽰当前的 接收者 我们使⽤ this 表达式:
在类的成员中,this 指的是该类的当前对象。
在扩展函数或者带有接收者的函数字⾯值中, this 表⽰在点左侧传递的 接收者 参数。
/热依扎图片 个人资料
/Lambda 表达式(函数字⾯值)
val sum2: Int.(Int)-> Int ={ other ->
plus(other)//这⾥直接调⽤了Int的plus()⽅法,也可以写成 this.plus(other)
}
词语大全四字词语当接收者类型可以从上下⽂推断时,lambda 表达式可以⽤作带接收者的函数字⾯值。
参考