scala中的val,var和lazy
转自:https://yerias.github.io/2020/03/19/scala/3/#3%EF%BC%9Alazy%E4%BF%AE%E9%A5%B0%E7%AC%A6%E5%8F%AF%E4%BB%A5%E4%BF%AE%E9%A5%B0%E5%8F%98%E9%87%8F%EF%BC%8C%E4%BD%86%E6%98%AF%E8%BF%99%E4%B8%AA%E5%8F%98%E9%87%8F%E5%BF%85%E9%A1%BB%E6%98%AFval%E4%BF%AE%E9%A5%B0%E7%9A%84
1:内容是否可变:val修饰的是不可变的,var修饰是可变的
下面看一段代码,你猜是否有错误
对象 ValAndVar { // val修饰由不可变性必须初始化val LOVE:字符串 = _ var SEX:字符串 = _ def main(args: Array [ String ]): Unit = { val name = “ tunan” var age = 18 // val修饰因不可伸缩不能重新赋值值
name = “ zhangsan”
age = 19
}
}
真实结果:
- val是不可变的,所以修饰的变量必须初始化
- val是不可变的,所以修饰的变量不能重新赋值
- val是不可变的,所以是多线程安全的
- val是不可变的,不用担心会改变它修饰的对象的状态
- val是不可变的,增强了代码的附加性,不用担心它的内容发生变化
- var是可变的,可以增强代码的补充,和val互补
2:val修饰的变量在编译后放入java中的中的变量被final修饰
先看源代码
对象 ValAndVar { val LOVE: String = “篮球” var SEX: String = _ def main(参数: Array [ String ]):单位 = { val名称: String = “ tunan” var age: Int = 18 }}
再看反编译后的代码(只保留了我们想要的部分)
public final class ValAndVar $ {
public static ValAndVar $ MODULE $; 私有最终的String LOVE ; public void main(String [] args){ 字符串名称= “ tunan”; 年龄= 18 ; } }同时字节码(bytecode)不表达一个局部变量是不可变的(immutable),答案是正确的,对于val或者final都只是给编译器用的,编译器如果发现你给此变量重新赋值会引发错误。的能力。我们发现这段代码很奇怪异,scala中的类变量,在字节码转换转换成parifate final,而main方法中的变量却没有添加final修饰,这是否证明编译器有问题?
所以就有了现在结果。
3:lazy修饰符可以修饰变量,但是这个变量必须是val修饰的
在证明lazy修饰的变量必须是val之前,我们先看看lazy是什么?
Scala中使用关键字lazy来定义无限变量,实现连续加载(懒加载)。
初始化变量只能是不可变变量,并且只能在调用初始化变量时,才会去实例化这个变量。在Java中,一般使用get和set实现延迟加载(懒加载),而在Scala中对延迟加载这一特性提供了语法等级的支持:
惰性 val名称= initName()
如果不使用lazy关键字对变量修饰,那么变量名称是立即实例化的,下面将通过多个案例对比认识:使用lazy关键字修饰变量后,只有在使用该变量时,才会调用其实例化方法。而在定义名称= initName()时并不会调用initName()方法,只有在后面的代码中使用变量名时才会调用initName()方法。
不使用lazy修饰的方法:
对象 LazyDemo { def initName: String = { println( “ initialinitName”) return “返回intName” } def main(args: Array [ String ]): Unit = { //懒惰的val名称= initName val的名称= initName //程序走到这里,就打印了initName的输出语句 println( “ hello,欢迎来到图南之家”) println(name) //程序走到这里,打印initName的返回值 }}
结果:上面的名称没有使用lazy关键字进行修饰,所以name是立即实例化的。
初始化initName
你好,欢迎来到图南之家
返回intName对象 LazyDemo { def initName: String = { println( “ initialinitName”) return “返回intName” } def main(args: Array [ String ]): Unit = { lazy val name = initName //不调用initName方法,即不打印initName中的输出语句// val name = initName println( “ hello,欢迎来到图南之家”) //打印main方法中的输出语句 println(name) //打印initName的输出语句,打印返回值 }}使用lazy修饰后的方法:
结果:在声明名称时,并没有立即调用实例化方法initName(),甚至在使用名称时,只会调用实例化方法,并且无论调用多少次,实例化方法只会执行一次。
你好,欢迎来到图南之家
初始化initName
返回intName证明lazy只能修饰的变量只能使用val
我们发现名称都是使用val修饰的,如果我们使用var修饰会怎么样呢?
我们发现报错:
'lazy' modifier allowed only with value definitions
实际上就是认为
lazy
修饰的变量只能val
修饰
scala中的val,var和lazy的更多相关文章
- Scala中的类和对象
类的定义 使用class定义 类的字段 在类中使用var,val定义字段 类的方法 scala中,使用var定义字段默认提供setter和getter方法对应名称为 value_= 和value /* ...
- Programming In Scala笔记-第七章、Scala中的控制结构
所谓的内建控制结构是指编程语言中可以使用的一些代码控制语法,如Scala中的if, while, for, try, match, 以及函数调用等.需要注意的是,Scala几乎所有的内建控制结构都会返 ...
- Scala 中的可变(var)与不可变(val)
引言 Scala 中定义变量分为 var(可变变量)和 val(不可变变量) Scala 中集合框架也分为可变集合和不可变集合.比如 List(列表) 和 Tuple(元组)本身就是不可变的,set ...
- scala中lazy
Scala中通过lazy关键字来定义惰性变量,惰性变量只能是不可变变量.只有在调用惰性变量的时候,才会去实例化这个变量
- Scala中Iterator允许执行一次
背景 使用spark执行mapPartitionsWithIndex((index,iterator)=>{....}),在执行体中将iterator进行一次迭代后,再次根据iterator执行 ...
- Scala中的构造器
Scala中的构造器 Scala中的构造器分为两类,主构造器和辅助构造器 主构造器是通过类名后面跟的括号里加参数列表来定义 辅助构造器是通过关键字this定义 定义一个无参主构造器 class rec ...
- Scala中的构造器和高阶函数
构造器 在定义类时可以定义主构造器.主构造器可以同时声明字段. /** * 主构造器 * @author Administrator */ //在scala中,类和方法交织在一起 class Test ...
- Scala中Stream的应用场景及事实上现原理
欢迎訪问我的独立博客:http://cuipengfei.me/blog/2014/10/23/scala-stream-application-scenario-and-how-its-implem ...
- scala中java并发编程
Runnable/Callable 线程(Thread) Executors/ExecutorService Future 线程安全问题 示例:搜索引擎 解决方案 Runnable/Callable ...
随机推荐
- 子网划分和VLAN
子网划分 IP地址的结构和分类 根据tcp/ip协议,连接在Internet上的每个设备都必须有一个IP地址,它是一个32位二进制数,为了方便人类识别,我们将它用点分十进制表示,每8位分为一段. IP ...
- 【Azure Redis 缓存 Azure Cache For Redis】Redis出现 java.net.SocketTimeoutException: Read timed out 异常
问题描述 在使用Azure Redis时,遇见Read Timed out异常, Redis的客户端使用的时jedis.问题发生时,执行redis部分指令出错,大部分get指令,set指令能正常执行. ...
- MySql中varchar和char,如何选择合适的数据类型?
背景 学过MySQL的同学都知道MySQL中varchar和char是两种最主要的字符串类型,varchar是变长的类型,而char是固定长度.那关于如何选择类型就成为令人头疼的事,很多初学者为了保证 ...
- python随机生成经纬度(用于爬虫参数伪造)
import random import math def generate_random_gps(base_log=None, base_lat=None, radius=None): radius ...
- IntentService下载任务
onHandleIntent开启一个线程按顺序处理任务,不适合做大量任务 public class MainActivity extends AppCompatActivity { protected ...
- mysql幻读、MVCC、间隙锁、意向锁(IX\IS)
IO即性能 顺序主键写性能很高,由于B+树的结构,主键如果是顺序的,则磁盘页的数据会按顺序填充,减少数据移动,随机主键则可能由于记录移动产生很多io 查询二级索引时,会再根据主键id获取数据页,产生一 ...
- 微信小程序UI自动化: minium文档部署
目录 参考资料 1. 在线文档(临时) 2. 本地部署 参考资料 https://git.weixin.qq.com/minitest/minium-doc 1. 在线文档(临时) 其实上面的链接里面 ...
- HP UNIX 查看 修改IP地址
# 查看所有IP地址h01_root[/]# lanscan Hardware Station Crd Hdw Net-Interface NM MAC HP-DLPI DLPI Path Addre ...
- redis方法-
//链接错误注意 //1.防火墙 //2.配置文件IP绑定 $redis = new Redis(); //连接redis $redis->connect('127.0.0.1', 6379); ...
- python机器学习实现K-近邻算法(KNN)
机器学习 K-近邻算法(KNN) 关注公众号"轻松学编程"了解更多. 以下命令都是在浏览器中输入. cmd命令窗口输入:jupyter notebook 后打开浏览器输入网址htt ...