scala中的val var可变与不可变是针对对象的,而不是其自身的值

最近刚学scala,对val var可变与不可变感觉很迷惑,然后看了一些博客发现

因为Scala的数据类型和数据结构全部都是用类来封装的,所以Scala中的可变与不可变都是针对类的实例对象的,

val不可变指的是不能改变初始化时指向的类的实例对象,但是这个对象自己的值可以变

var可变指的是可以改变初始化时指向的类的实例对象,而且这个对象的值或者新指向的对象的值可以变

用一个很多博客都举的例子:

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变量的影响

对于可变的数据结构,进行操作直接改变原数据结构对象的值,所以val指向的数据结构的对象不变,所以可以操作成功

但是对于不可变的数据结构,进行操作改变的不是原数据结构对象的值,而是返回一个新的数据结构对象,这时需要改变val指向的数据结构,所以报错

例如

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

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值