Scala学习笔记-apply方法

来源:互联网 发布:python for in循环 编辑:程序博客网 时间:2024/06/06 04:55

Scala-apply方法

参考:lyrebing的CSDN博客

这里写图片描述

Scala是一种构建在JVM之上的静态类型脚本语言,而脚本语言会有一些约定来增强灵活性,下面看两条在日常开发中常见的约定:

约定1:在明确了调用者的前提下,若方法只有一个参数,则调用时就可以省略括号,例如0 to 2的完整调用是0.to(2),但是println(10)就不能简写成 println 10,因为没有明确方法的调用者。


约定2:用括号给一个变量(对象)传递参数时,scala会把它转换成对apply方法的调用。

apply方法可以定义在class中,也可以定义在object中,这两种方式有所区别,但本质是一样的,下面列举一个简单是示例来说明apply方法的用法。

  • 在class中定义apply方法
class ApplyTest{    def apply() = println("I am into spark so much!!!")    def apply(p: String) = println("apply with one param:" + p)    def haveATry: Unit ={        println("have a try on apply")    }}object ApplyOperation{     def main (args: Array[String]) {         val array= Array(1,2,3,4)         val a = new ApplyTest()          a.haveATry         a()  //调用无参apply         a("adsffdsa") //调用带参数的apply    }}

根据约定,我们用括号想对象中传递参数,scala编译器会将其转换成对apply方法的调用,需要注意的是class中的apply方法指向具体的对象。

编译后的部分代码如下:

public final class ApplyOperation${  public static final  MODULE$;  static  {    new ();  }  public void main(String[] args)  {    int[] array = { 1, 2, 3, 4 };    ApplyTest a = new ApplyTest();    //此处是关键    a.haveATry();    a.apply();    a.apply("adsffdsa");  }  private ApplyOperation$() { MODULE$ = this;  }}
  • 在object中定义apply方法
    在前面讲过,被object定义出来的是一个static final的单例对象,那么一个被定义在object中的apply方法与这个单例对象之间有什么联系呢?先看代码示例
class ApplyTest{    def apply() = println("I am into spark so much!!!")    def apply(p: String) = println("apply with one param:" + p)    def haveATry: Unit ={        println("have a try on apply")    }}object ApplyTest {    def apply(a: String, b: String) = {        println(a + ",," + b)    }}object ApplyOperation{     def main (args: Array[String]) {         val a = ApplyTest("s","n")      }}

由于ApplyTest是一个单例对象,所以,按照约定,用括号向对象中传递参数时,会调用apply方法。对于上面的示例,就是在单例对象ApplyTest上调用apply(a,b)方法,可以通过编译后的源码来验证这一点

import scala.runtime.BoxedUnit;public final class ApplyOperation${  public static final  MODULE$;  static  {    new ();  }  public void main(String[] args)  {    //此处是重点    ApplyTest..MODULE$.apply("s", "n"); BoxedUnit a = BoxedUnit.UNIT;  }  private ApplyOperation$() { MODULE$ = this;  }}

从上面的代码中可以看出,确实是在单例对象 MODULE$上调用的apply方法。

0 0