scala中val与def定义的区别
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定义的区别相关推荐
- Scala中val, lazy, def的区别
2019独角兽企业重金招聘Python工程师标准>>> val strVal = scala.io.Source.fromFile("test.txt").mkS ...
- Jquery中.val()与.value之间的区别
三年多没敲过代码了,今年打算捡起来,是需要多么大的勇气.但是为了实现自我价值,履行自我的承诺,这就是责任.没有什么难不难,晚不晚之说,是我经常对别人说的那样,再晚不过心晚,,一切努力了,实现了每一天的 ...
- Scala中 class和case class的区别
在Scala中存在case class,它其实就是一个普通的class.但是它又和普通的class略有区别,如下: 1.初始化的时候可以不用new,当然你也可以加上,普通类一定需要加new: scal ...
- scala中NULL的option定义的字段初始化用Some
例子: var in = None:Option[FileInputStream] var out = None:Option[FileOutputStream] try{in = Some(new ...
- scala中val function
示例 val add1 = (i: Int) => i + 1 // implicit return type (IRT) val add1: Int => Int = (i) => ...
- scala中object和class关键字的区别
- Scala中的类和对象
类的定义 使用class定义 类的字段 在类中使用var,val定义字段 类的方法 scala中,使用var定义字段默认提供setter和getter方法 对应名称为 value_= 和value 1 ...
- Scala中集合类型与java中集合类型转换
对于java中的集合元素并不能在scala中拿来就用的,需要进行相应的转换. 1. 转换规则如下 从下面可以看出,有些可以相互转换的,有些只能单向转换: scala.collection.Iterab ...
- C语言中的声明和定义
C语言中的声明和定义 引言 变量的定义和声明 函数的定义和声明 引言 之前一直没有在意过C语言中的声明和定义的区别,和同事交流代码时也总是混淆这个概念,害!归根究底还是C语言基础没打好. 变量的定义和 ...
最新文章
- 嵌入式设备web服务器比较
- mysql未知数据库_如何处理这个错误(1049,“未知数据库”/ users / ohyunjun / work / astral / mysql“”)...
- word 插入代码_Word教程:最神奇的快捷键:Alt+X,一秒变出各种符号!
- java.io设计模式_Java IO文件过滤器对命令设计模式的使用
- Linux下载源码编译出错,linux下fortran中编译代码时“undefined reference to `_gfortran_st_”错误...
- EJB3.0 Timer
- Assimp Android 编译
- dva开发一个cnode网站(2) 1
- 【数据分析案例】留存率分析方法
- 秋天的第一杯奶茶?NO,是第一份大数据学习宝典
- 迪文屏中关于MODBUS的接口配置
- python获取ip所在地详细地址_Python 获取本机 IP 地址
- #cs231n#Assignment2:Dropout.ipynb
- Tableau仪表板制作
- 淘宝模块中宝贝跳转链接
- 名编辑电子杂志大师教程 | 如何直接输出安卓apk格式?
- 【物联网】老程序教你一招,10行代码让超声波模块秒变声控开关
- Easyweb包括iframe中的页面跳转
- 素描初学者入门教程素描高手分享经…
- 云服务器ECS(一)
热门文章
- SWUST OJ#978 #979 #980 二叉树的遍历
- pycharm如何将英文设置为中文(详细教程)
- Java实现Token登录验证(基于JWT的token认证实现)
- 程序员是如何通过一张图片获取GPS信息的?简单得不敢相信
- 无线接入网络之异构接入网络(HetNet)
- hotmail在outlook2007设置邮箱(完美解决)
- 感恩CSDN,感谢有你
- 什么是arm-arm体系架构版本(指令集版本)-arm内核版本
- 前端基础知识面经大全(含html/css/js/es6/计算机基础)
- 燃气管网在线监测系统方案