Val 和Var 的区别

一、最直观的就是:val定义的变量不能被再次赋值,而var定义的可以,见下图

scala> val s=10
s: Int = 10scala> s=11
<console>:27: error: reassignment to vals=11^scala> var a=10
a: Int = 10scala> a=11
a: Int = 11

二、事实上,var 修饰的对象引用可以改变,val 修饰的则不可改变,但对象的状态却是可以改变的。

class A(n: Int) { var value = n //利用可变修饰符定义一个值
}
class B(n: Int) { val value = new A(n) //利用不变修饰符定义一个值
} class C(n: Int) { var value = new A(n) //利用可变修饰符定义一个值
}object Test { def main(args: Array[String]) { val x = new B(5) //首先定义一个不可变变量x,所以下一行会报错x = new B(6) // 错误,因为 x 为 val 修饰的,引用不可改变 x.value = new A(6) // 错误,因为 x.value 为 val 修饰的,引用不可改变 val y = new C(5) //定义一个不可变变量y,但是y.value是 var修饰的,所以下一行正确y.value = new A(7) //因为y.value 是var修饰的。当然y = new C(7)依然报错,因为y是val修饰的x.value.value = 6 // 正确,x.value.value 为var 修饰的,可以重新赋值 }
}

仔细看上面的备注解释,就可以明白var和val的区别了;

针对变量的不变性,使用val的好处:

一是,如果一个对象不想改变其内部的状态,那么由于不变性,我们不用担心程序的其他部分会改变对象的状态;

二是,当用 var 修饰的时候,你可能在多个地方重用 var 修饰的变量,这样会产生下面的问题:

  • 对于阅读代码的人来说,在代码的确定部分中知道变量的值是比较困难的;
  • 你可能会在使用代码前初始化代码,这样会导致错误;

针对变量的可变性,使用var的好处:

  • 使用可变性可以大幅度提高程序的执行效率。
  • 避免了由于其他用途而对变量进行重用

三、def需要注意的地方

abstract class Person {def id: Int
}
class Student extends Person{override var id = 9527  //Error: method id_= overrides nothing
}

上述继承时,发生错误,因为用def定义的成员变量,不具备setter和getter方法。

那么如果父类中只定义了一个方法def id: Int,用来生成用户的id,而子类用var变量重写这个方法的话override var id = 9527,编译会报错method id_=overrides nothing,从报错中可以看出来,由于scala会为var变量自动生成了一个setter方法(id_),但是父类并没有这个方法,所以是无法重写的。

如果改下,必须为以下代码,此时重新定义了父类的setter方法

abstract class Person {def id: Int  def id_=(value: Int) //父类必须有set方法
}
class Student extends Person{override var id = 9527 //为var变量自动生成get和set方法
}

也可以利用var定义函数的成员变量

abstract class Person1 {var id: Int
}
class Student extends Person1{var id = 9527 //为var变量自动生成get和set方法
}

这样就可以直接使用了,不会出错了。

spark scala中的var 和val、def区别对比相关推荐

  1. kotlin中的var和val与编译时常量

    我们都知道,在kotlin中,var定义的变量是可读可变的,而val定义的变量是只读不可变的,这是为什么呢?这里我们来看下面的代码: class Player{val name = "jac ...

  2. Scala中 class和case class的区别

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

  3. Kotlin中var和val的区别

    var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量.这种声明变量的方式和java中声明变量的方式一样. val是一个只读变量,这种声明变量的方式相当于java中的final变量.一个 ...

  4. Scala 变量定义/类型推导/var和val的区别

  5. Kotlin入门:var和val的区别

    Kotlin中有两个关键字定义变量 var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量.这种声明变量的方式和java中声明变量的方式一样. val是一个只读变量,这种声明变量的方式相 ...

  6. var和val的区别

    var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量.这种声明变量的方式和java中声明变量的方式一样. val是一个只读变量,这种声明变量的方式相当于java中的final变量.一个 ...

  7. SystemVerilog中logic var reg wire的区别

    在Verilog中,所有的线网和变量都是使用四态值,因此没必要也不能清晰的区分信号类型. 为了增强灵活性,SystemVerilog中定义信号同时具有类型和数据类型两个属性. 类型指示信号是属于线网( ...

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

  9. JUnit4 中@AfterClass @BeforeClass @after @before的区别对比

    JUnit4使用Java5中的注解(annotation),以下是JUnit4常用的几个annotation:  @Before:初始化方法   对于每一个测试方法都要执行一次(注意与BeforeCl ...

最新文章

  1. 数字人民币解密:数字人民币的系统架构、产品形态是什么样的?
  2. 抖音推荐机制与算法探讨
  3. Spring事务管理机制
  4. oracle adg切换原理,oracle11g ADG主备切换
  5. st link v2引脚连接_ST-Link资料02_ST-Link固件介绍,及固件命名规则
  6. jdk7与jdk8环境共存与切换
  7. Redis 突然变慢了如何排查并解决?
  8. SLAM大神总结(转载)
  9. myEclipse的subversion插件Subclipse
  10. Oralce weblogic 11g 安装部署使用手册
  11. Tasker to stop Poweramp control for the headset while there is an incoming SMS - frozen
  12. Flask 的路由系统 FBV 与 CBV
  13. Springboot毕设项目餐厅后勤管理系统cxjgl(java+VUE+Mybatis+Maven+Mysql)
  14. 关于ADS-Matlab联合仿真ADS.RunSimulation()报错的解决方案
  15. 智能衣橱控制系统的设计
  16. 简单易懂读《重构》 - Refused Bequest (拒绝继承的遗赠)
  17. 专注物联网人工智能服务 云知声芯起航
  18. 如何创建Qt quick应用程序
  19. java中jdbc查询有返回值_使用JdbcTemplate查询方法的返回值 | 学步园
  20. 如何在以太坊网络上发布自己的代币

热门文章

  1. Golang Vue 后台框架 go-admin 从零开始企业级实战视频教程(33 个视频)
  2. ​​​​​​​ABBYY FineReader PDF中文版图片转文字识别工具
  3. 力扣978最长湍流子数组——Python解答
  4. [VC] 学习外挂心得
  5. 深圳一服装厂如何利用大数据塑造核心竞争力转型先进制造业?
  6. Maya奔跑动画制作
  7. 一线|《小小的愿望》上映首日挤落《罗小黑》,中秋档才是真战场
  8. UI设计中最重要的颜色
  9. 堆转储上的线程:_妖精陷阱:线程转储分析模式
  10. [IT新应用]如何拯救死机的苹果手机(iPhone X)