断断续续学习scala也有一段时间了,初期总对val 与var 的理解不太透彻,今天来做做总结。

一般都知道val 表示不可变,var表示可变,比如:

val s ="hello"
s="world"//错误,不能对val重新赋值
var i=1
i=2//没有问题 

但是在碰到可变与不可变数据结构的时候,容易造成迷惑:

val numbers= ArrayBuffer(1,2,3)
numbers+=5//success
var numbers=Set(1,2,3)
numbers+=5//success

咋一看val不是不可变的吗,怎么能numbers+=5? 
val numbers指向了一个可变的数据结构 数组缓冲ArrayBuffer ,numbers是可以进行 
numbers+=5操作的, 这是因为所指的这个对象是有自己的状态的,比如这里的对象是ArrayBuffer类型,这个的对象的状态是可以改变的,但是你不能val numbers =ArrayBuffer(1,2) 了,被val声明的numbers只能指向这个对象,但是这个对象自身的状态是可以改变的(因为是类型是数组缓冲) 
再看下一个: 
Set是一个不可变对象,被声明为var的numbers指向,numbers+=的意义是什么呢?它返回一个新的对象Set(1,2,3,5) 原来的Set(1,2,3) 你无法改变,因为他是一个不可变的对象,这个新的Set再重新被指向了numbers. 要明白,可变对象数组缓冲的方法“+=”返回的是修改后的原来的集合,而不可变对象Set的“+=”返回的是一个新的集合。

为了证明对象自身是有状态的,再看一下StackOverFlow上面的例子:

class A(n: Int) {var value = n
}class B(n: Int) {val value = new A(n)
}object Test {def main(args: Array[String]) {val x = new B(5)x = new B(6) // Doesn't work, because I can't replace the object created on the line above with this new one.x.value = new A(6) // Doesn't work, because I can't replace the object assigned to B.value for a new one.x.value.value = 6 // Works, because A.value can receive a new object.}
}

可以看到 x 与x.value都不能被重新赋值,以为他们都被val声明,一旦指向一个对象就不能再被指向其他的对象了, 但是这个对象自身的状态是会改变的,例如x.value.value就能被重新赋值了。

  • val定义值时,会做call-by-value操作,
  • def则会做call-by-name操作。
  • 使用 def 每次都会重新进行取值。

    那么对应上面的情况,如果文件内容改变,由于方法体在被调用时会重新执行,将得到被修改后文件的内容。

 // 这是一个死循环def loop: Boolean = loop// 用val定义时会做call-by-value,以下语句会block住val x = loop // 用def定义时,是做的call-by-name。故以下语句暂时不会执行,在用到y的时候才做evaluationdef y = loop

scala 中的val 、 var 、def相关推荐

  1. 在Scala中评估val,var,lazy val和def构造时

    发表简短目录 (Post Brief TOC) Introduction介绍 Scala 'val' usageScala" val"用法 How Scala 'val' is E ...

  2. Scala中的类和对象

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

  3. Scala 中的 特质(trait)

    文章目录 特质(trait) 概念 语法 继承特质 继承单个trait 代码示例 继承多个特质 代码示例 定义具体的方法 代码示例 trait中定义具体的字段和抽象的字段 定义 代码示例 模板模式 代 ...

  4. scala中val与def定义的区别

    scala中val与def定义的区别 变量 val定义一个不可改变的变量, def则是一个方法: //scala中定义: def main(args: Array[String]): Unit = { ...

  5. scala 中List的简单使用

    /*** scala 中List的使用**/object ListUse {def main(args: Array[String]): Unit = {def decorator(l:List[In ...

  6. Scala中没有break和continue, 如何退出循环

    Java是指令式风格,Scala是函数式风格. 在Scala中,应该尽量适用循环,而是应用函数的方式来处理. Scala并没有提供break和continue语句来退出循环,那么如果我们又确实要怎么办 ...

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

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

  8. scala条件替换_scala - 有没有办法用scala中的高阶方法替换嵌套的For循环 - SO中文参考 - www.soinside.com...

    有没有办法用scala中的高阶方法替换嵌套的For循环 问题描述 投票:0回答:1 我有一个mutableList,并希望获取所有行的总和,并根据某些条件将其行替换为其他值.下面的代码对我来说工作正常 ...

  9. Scala中的Map使用例子

    Map结构是一种非常常见的结构,在各种程序语言都有对应的api,由于Spark的底层语言是Scala,所以有必要来了解下Scala中的Map使用方法. (1)不可变Map 特点: api不太丰富 如果 ...

最新文章

  1. 暗时间:开发效率为何如此低下
  2. 微服务该如何设计缓存?
  3. Rhel6.0部署Oracle10g报错相关问题记录
  4. 解决IDEA快捷键 Alt+Insert 失效的问题
  5. python可视化窗口编程-Python可视化界面编程入门
  6. camel apache_Apache Camel 3只有2个月的路程
  7. 【计算机视觉】论文笔记:Ten years of pedestrian detection, what have we learned?
  8. Tools:Android studio 使用
  9. js进阶正则表达式14验证邮编(input的pattern属性)(正则表达式加起^始$)
  10. wpf 切换搜狗输入法英文_搜狗输入法使用技巧整理,建议保存收藏
  11. 【最小开发板】Attiny85开发与实践
  12. Simulink嵌入式自动代码 DSP F28335(1)——环境配置和方波例程
  13. Google Driver 询问国内手机号怎么办,谷歌云盘下载配额不足
  14. August 2007
  15. 等额本息与等额本金,从财务管理的角度充分考虑货币时间价值,哪个对于购房人来说更划算?
  16. 小技巧:如何创建公共邮箱?教育邮箱创建哪个好?
  17. 中忻嘉业:抖音小店主要引流玩法
  18. 什么是AT指令,AT指令是什么
  19. 11部程序员大电影你看过几个?
  20. AT1983 BBQ Hard

热门文章

  1. 安阳师范学院计算机应用技术在哪个校区,安阳师范学院有几个校区及校区地址 哪个校区最好...
  2. 在Unity中实现音口同步-01-概述
  3. ABAP_RFC_BAPI培训教程
  4. 易通超市(百货版) 2009 注册机
  5. PythonGUI编程!使用Tkinter制作快递查询软件!是不是很实用呢!
  6. 区间素数 由N(N<=10000)个整数组成的数组,其中连续K(K<=200)个元素构成一个区间,称为K区间。一个K区间中所有素数的和记为Sk,请计算整个数组中,所有K区间中的最大Sk值,并输出。
  7. 电脑通过手机(摩托E2)上网
  8. linux 编程 生成.img,从头开始生成 SELinux
  9. [转载]如果你想练练视频识别,那么这些数据集或许可以为你所用
  10. 博客摘录「 3种交叉验证与参数选择方式」2023年5月17日