Scala-值和变量
scala中的变量有两种,一种是可变的,用var来声明,另一种的不可变的用val来声明,下面我们就来简要说明一下。
首先,用val声明一个不可变的变量msg1,从结果中可以看到msg1的类型为String
scala> val msg1 = "hell world"
msg1: String = hell world
scala>
那么既然val是迎来声明不可变的变量,如果对其值进行修改会发生什么事呢?
scala> msg1 = "update content"
<console>:11: error: reassignment to val
msg1 = "update content"
^
scala>
此时,编译器给出了一个非常明确的错误提示:对一个 val 再次复制是错误的。
由于scala是基于一门基于Jvm的函数式编程语言,那么底层一定严格遵循Java的语法规范,那么问题来了,val变量怎么与Java映射?
我们来定义一个类,这个类仅包含一句val变量的声明:
class Test {
val msg = "HelloWorld"
}
然后利用scalac将其编译成class文件,在进行反编译
scalac Test.scala
反编译后的源码如下:
public class Test
{
private final String msg = "HelloWorld";
public String msg() {
return this.msg;
}
}
一目了然了。
与val相对应的是var,var类型的变量在声明后可以对其内容进行修改
scala> var msg2 = "Hello World"
msg2: String = Hello World
scala> msg2 = "update context"
msg2: String = update context
scala>
同样,我们看一下val变量对应的Java源码
public class Test
{
private String msg = "HelloWorld";
public String msg() { return this.msg; }
public void msg_$eq(String x$1) { this.msg = x$1; }
}
可以看到,var的变量不在是final的,同时,还多列一个设值器方法msg_ eq(Stringx 1),这完全符合Java编码规范。
细心的同学可能已经看到了,无论是val还是var,在变量声明的过程中,都没有像Java那样,指定变量的具体类型
String msg = "Hello World"
这得益于scala的类型推断机制,scala编译器可以根据值类型来推断出变量的所属类型。
当然,在声明变量时,有时为了代码的可读性,也会添加变量类型的声明
scala> val msg3: String = "a"
msg3: String = a
scala> var msg4: String = "b"
msg4: String = b
scala>
这样做有两点好处,第一、可以使代码更加清晰可读,第二、可以让编译器和程序猿的想法保持一致。
总结:
- val变量赋值后不能对其改变
- var变量赋值后可以对其修改
- 在声明var或val变量时,可以不显式制定变量的类型
- val变量对于Java中的final字段