spark scala中的var 和val、def区别对比

Val 和Var 的区别

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

scala> val s=10
s: Int = 10

scala> s=11
<console>:27: error: reassignment to val
         s=11
          ^

scala> var a=10
a: Int = 10

scala> 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方法
}

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

猜你喜欢

转载自blog.csdn.net/a627082796/article/details/87873889