美文网首页Kotlin程序员
搞定Kotlin Receiver

搞定Kotlin Receiver

作者: 欧阳锋 | 来源:发表于2018-04-26 18:13 被阅读33次

    Kotlin官方文档中没有针对Receiver的专题讲解,但这个知识点却贯穿在了整个基础体系中。这节课我们将彻底揭开Receiver的神秘面纱,带你一探究竟。

    什么是Receiver

    解释这个概念之前,先想一想为什么会有这个东西,在Java语言中是否存在相似的概念。直接来看一个例子:

    String str = "123";
    Long value = Long.parseLong(str);
    

    这是Java语言中非常常见的一段代码,将数字字符串转换为Long。如果使用Kotlin实现类似的需求,我们会怎么做的呢?看代码:

    val str = "123"
    val value = str.toLong()
    

    干脆利落!事实上,JDK的String类并没有toLong方法。之所以能够如此优雅地将字符串转换为Long主要归功于Kotlin的扩展语法。看一眼toLong的官方实现:

    public inline fun String.toLong(): Long = java.lang.Long.parseLong(this)
    

    可以看到,toLong方法使用了String前缀标识,这意味着toLong方法是为String扩展的。在Kotlin语言中,你将可以直接使用点语法调用这个扩展方法,String就称之为toLong方法的Receiver。同样地,如果toLong前缀是Int,Int就称之为toLong方法的Receiver。

    那么,问题来了。Java语言中并没有扩展语法,在Java语言中如何调用toLong方法呢?

    这里恰好用到了Receiver的概念,Kotlin编译器会生成一个与声明扩展的文件同名加Kt的类,扩展方法将作为该类的静态方法,使用的时候要求传入Receiver。因此,在Java端调用toLong类似这样:

    String str = "123";
    Long value = StringKt.toLong(str);
    

    实际上,在Kotlin语言中,类不再是语言的最小单位。我们既可以单独声明一个全局函数,也可以声明全局变量。因此,你可以认为toLong是一个函数整体,这个函数的接收者可以是任意对象。

    而对于Java,Java语言中所有的行为都必须在类体中完成。具体到某个函数或某一个变量始终属于某一个类实例。换而言之,其Receiver是固定的,也就没有了所谓Receiver的概念。

    多个Receiver

    事实上,在Kotlin语言中,同一个函数可能存在多个Receiver。那么,什么时候会出现这种情况呢?

    在扩展声明中,如果对应的前缀本身是一个泛型,就意味着当前函数的Receiver可能是满足泛型要求的任意对象。尤其如果是这样声明的话:

    fun <T> T.apply(block: () -> T): T {
          ...
    }
    

    这就意味着,所有类都是apply方法的Receiver,具体类型取决于你的调用对象。例如:如果这样调用Dog.apply(),当前apply的Receiver就是Dog。

    理解上下文

    这里说的上下文其实和JS里面的上下文有点像。刚刚学习Kotlin的同学容易产生一个困惑,在扩展方法中如何调用Receiver类中的方法。事实上,你的扩展方法恰好就处于Receiver实例的上下文环境中,你可以直接调用该Receiver类中的任意可访问方法。

    理解了上述概念后,再回到标准库中的方法讲解。仔细观察这几个方法,你会发现他们有一个共同点,都是执行了一个lambda表达式(repeat除外)。所不同的只有下面两个地方:

    • Receiver 这决定了当前block的上下文,有的函数Receiver是当前实例,有的函数可以自由指定Receiver,有的函数将Receiver作为参数传入block
    • block的类型不一样,有的block有返回值,有的没有返回值。有的返回Receiver本身,有的可以交给开发者指定。

    按照这个思路去理解这几个标准函数的用法,一切都会明朗起来。

    关注欧阳锋工作室,与锋同行

    欧阳锋工作室

    欢迎加入Kotlin交流群

    关于Kotlin,如果你有任何问题,欢迎加入我的Kotlin交流群: 329673958。当前群交流活跃,问题解决速度很快,期待你的加入。

    相关文章

      网友评论

        本文标题:搞定Kotlin Receiver

        本文链接:https://www.haomeiwen.com/subject/cxuplftx.html