scala中val与def定义的区别

变量

val定义一个不可改变的变量, def则是一个方法:

//scala中定义:
def main(args: Array[String]): Unit = {def a = "hello"val b = "hello"println(a)println(b)
}//编译之后的class文件
private final String a$1()
{return "hello";
}public void main(String[] args)
{String b = "hello";Predef..MODULE$.println(a$1());Predef..MODULE$.println(b);
}

方法

下面我们分别对应这四种定义方式,与反编译后的java比较一下,从而深层次理解def与val在方法中怎么实现的

class Test {def even1: (Int => Boolean) = (_ % 2 == 0)val even2: (Int => Boolean) = (_ % 2 == 0)def even3(x: Int): Boolean = {x % 2 == 0}lazy val even4: Int => Boolean = _ % 2 == 0
}

1. def a = ()

def even1: (Int => Boolean) = (_ % 2 == 0), 通过编译我们可以看到,每次调用even1 都会实例化一个对象,这显然不是我们愿意看到的

  public Function1<Object, Object> even1(){new AbstractFunction1.mcZI.sp(){public static final long serialVersionUID = 0L;public boolean apply$mcZI$sp(int x$1){return x$1 % 2 == 0;}public final boolean apply(int x$1){return apply$mcZI$sp(x$1);}};}

2. val =

val even2: (Int => Boolean) = (_ % 2 == 0),实现了Function1, 并且实例化该对象

public Function1<Object, Object> even2()
{return this.even2;
}private final Function1<Object, Object> even2 = new AbstractFunction1.mcZI.sp()
{public static final long serialVersionUID = 0L;public boolean apply$mcZI$sp(int x$2){return x$2 % 2 == 0;}public final boolean apply(int x$2){return apply$mcZI$sp(x$2);}
};

3.def a() = {}

这种方法定义相比java比较常规,容易接受

def even3(x: Int): Boolean = {x % 2 == 0
}
编译之后如下:
public class Test
{public boolean even3(int x){return x % 2 == 0;}
}

4.lazy val

lazy val even4: Int => Boolean = _ % 2 == 0,对比even2, 实现了懒加载

  private Function1<Object, Object> even4;private volatile boolean bitmap$0;public Function1<Object, Object> even4(){return this.bitmap$0 ? this.even4 : even4$lzycompute();}private Function1 even4$lzycompute(){synchronized (this){if (!this.bitmap$0){this.even4 = new AbstractFunction1.mcZI.sp(){public static final long serialVersionUID = 0L;public boolean apply$mcZI$sp(int x$1){return x$1 % 2 == 0;}public final boolean apply(int x$1){return apply$mcZI$sp(x$1);}};this.bitmap$0 = true;}return this.even4;}}

我们再看一个比较复杂的例子

方法里面定义方法

class Test {def fun1(x: Int): Int = {def fun1_2() = {println("fun1_2=>" + x)}fun1_2()println("fun1")2 * x}val fun2 = (x: Int) => {val fun2_2 = () => {println("fun2_2=>" + x)}fun2_2()println("fun2")2 * x}
}

反编译后的java代码如下:

public class Test
{private final void fun1_2$1(int x$1){Predef..MODULE$.println(new StringBuilder().append("fun1_2=>").append(BoxesRunTime.boxToInteger(x$1)).toString());}public int fun1(int x){fun1_2$1(x);Predef..MODULE$.println("fun1");return 2 * x;}public Function1<Object, Object> fun2(){return this.fun2;}private final Function1<Object, Object> fun2 = new AbstractFunction1.mcII.sp(){public static final long serialVersionUID = 0L;public final int apply(int x){return apply$mcII$sp(x);}public int apply$mcII$sp(final int x){Function0 fun2_2 = new AbstractFunction0.mcV.sp(){public static final long serialVersionUID = 0L;public final void apply(){apply$mcV$sp();}public void apply$mcV$sp(){Predef..MODULE$.println(new StringBuilder().append("fun2_2=>").append(BoxesRunTime.boxToInteger(x)).toString());}};fun2_2.apply$mcV$sp();Predef..MODULE$.println("fun2");return 2 * x;}};
}

从例子可以看出来, def方法比较简单唯一的区别是,把方法提出去形成并列的两个方法,把这种闭包形式通过形参的方式传递给下一个方法, 而val方法通过实例化Function1接口来实现,对于fun2_2每次调用都会实例化对象,这个使我们编程中需要注意的

scala中val与def定义的区别相关推荐

  1. Scala中val, lazy, def的区别

    2019独角兽企业重金招聘Python工程师标准>>> val strVal = scala.io.Source.fromFile("test.txt").mkS ...

  2. Jquery中.val()与.value之间的区别

    三年多没敲过代码了,今年打算捡起来,是需要多么大的勇气.但是为了实现自我价值,履行自我的承诺,这就是责任.没有什么难不难,晚不晚之说,是我经常对别人说的那样,再晚不过心晚,,一切努力了,实现了每一天的 ...

  3. Scala中 class和case class的区别

    在Scala中存在case class,它其实就是一个普通的class.但是它又和普通的class略有区别,如下: 1.初始化的时候可以不用new,当然你也可以加上,普通类一定需要加new: scal ...

  4. scala中NULL的option定义的字段初始化用Some

    例子: var in = None:Option[FileInputStream] var out = None:Option[FileOutputStream] try{in = Some(new ...

  5. scala中val function

    示例 val add1 = (i: Int) => i + 1 // implicit return type (IRT) val add1: Int => Int = (i) => ...

  6. scala中object和class关键字的区别

  7. Scala中的类和对象

    类的定义 使用class定义 类的字段 在类中使用var,val定义字段 类的方法 scala中,使用var定义字段默认提供setter和getter方法 对应名称为 value_= 和value 1 ...

  8. Scala中集合类型与java中集合类型转换

    对于java中的集合元素并不能在scala中拿来就用的,需要进行相应的转换. 1. 转换规则如下 从下面可以看出,有些可以相互转换的,有些只能单向转换: scala.collection.Iterab ...

  9. C语言中的声明和定义

    C语言中的声明和定义 引言 变量的定义和声明 函数的定义和声明 引言 之前一直没有在意过C语言中的声明和定义的区别,和同事交流代码时也总是混淆这个概念,害!归根究底还是C语言基础没打好. 变量的定义和 ...

最新文章

  1. 嵌入式设备web服务器比较
  2. mysql未知数据库_如何处理这个错误(1049,“未知数据库”/ users / ohyunjun / work / astral / mysql“”)...
  3. word 插入代码_Word教程:最神奇的快捷键:Alt+X,一秒变出各种符号!
  4. java.io设计模式_Java IO文件过滤器对命令设计模式的使用
  5. Linux下载源码编译出错,linux下fortran中编译代码时“undefined reference to `_gfortran_st_”错误...
  6. EJB3.0 Timer
  7. Assimp Android 编译
  8. dva开发一个cnode网站(2) 1
  9. 【数据分析案例】留存率分析方法
  10. 秋天的第一杯奶茶?NO,是第一份大数据学习宝典
  11. 迪文屏中关于MODBUS的接口配置
  12. python获取ip所在地详细地址_Python 获取本机 IP 地址
  13. #cs231n#Assignment2:Dropout.ipynb
  14. Tableau仪表板制作
  15. 淘宝模块中宝贝跳转链接
  16. 名编辑电子杂志大师教程 | 如何直接输出安卓apk格式?
  17. 【物联网】老程序教你一招,10行代码让超声波模块秒变声控开关
  18. Easyweb包括iframe中的页面跳转
  19. 素描初学者入门教程素描高手分享经…
  20. 云服务器ECS(一)

热门文章

  1. SWUST OJ#978 #979 #980 二叉树的遍历
  2. pycharm如何将英文设置为中文(详细教程)
  3. Java实现Token登录验证(基于JWT的token认证实现)
  4. 程序员是如何通过一张图片获取GPS信息的?简单得不敢相信
  5. 无线接入网络之异构接入网络(HetNet)
  6. hotmail在outlook2007设置邮箱(完美解决)
  7. 感恩CSDN,感谢有你
  8. 什么是arm-arm体系架构版本(指令集版本)-arm内核版本
  9. 前端基础知识面经大全(含html/css/js/es6/计算机基础)
  10. 燃气管网在线监测系统方案