Scala基础:val vs var
变量
Scala 是一种多范式的编程语言,它融合了面向对象编程和函数式编程的各种特性。下面介绍scala的变量及用途。
-
不可变变量
Val
val username = "Kimi" username = "another" //编译错误 username值不可修改
- 特性:一旦一个
val
被初始化,它的值就不能被改变。 - 用途:用于确保变量在初始化后不会被修改,有助于保证程序的线程安全性和减少副作用。
类似于java的
final
- 特性:一旦一个
Java中的final变量、final方法、final类
- final变量:
final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。和scala中的val设计的用意大差不大。
通常情况定义为常量,赋值后不能变,不一定是要在定义时赋值。
而全局常量必须在定义时赋值,如
public static final double PI_VAULE = 3.14;
import java.util.Random; class Test { int i = 0; } /** * 常量示例 * * @author pan_junbiao * */ public class FinalData { static Random rand = new Random(); private final int VALUE_1 = 9; // 声明一个final常量 private static final int VALUE_2 = 10; // 声明一个final、static常量 private final Test test = new Test(); // 声明一个final引用 private Test test2 = new Test(); // 声明一个不是final的引用 private final int[] a = { 1, 2, 3, 4, 5, 6 }; // 声明一个定义为final的数组 private final int i4 = rand.nextInt(20); private static final int i5 = rand.nextInt(20); public String toString() { return "i4值:" + i4 + " i5值:" + i5 + " "; } public static void main(String[] args) { FinalData data = new FinalData(); // 报错:不能改变定义为final的常量值 // data.VALUE_1 = 8; // 报错:不能改变定义为final的常量值 // data.VALUE_2 = 9; // 报错:不能将定义为final的引用指向其他引用 // data.test = new Test(); // 正确: 可以对指定为final的引用中的成员变量赋值 data.test.i = 1; // 正确: 可以将没有定义为final的引用指向其他引用 data.test2 = new Test(); // 报错:不能对定义为final的数组赋值 // int b[] = { 7, 8, 9 }; // data.a = b; // 但是final的数组中的每一项内容是可以改变的 for (int i = 0; i < data.a.length; i++) { data.a[i] = 9; } System.out.println(data); // 自动调用类的toString方法 System.out.println("data2"); System.out.println(new FinalData()); } }
final的对象引用只能指向唯一一个对象,不可以指向其他对象,但是这个对象的值是可以改变的,数组同理,但是
static final
的值是完全不可更改的。import static java.lang.System.out; import java.util.Random; /** * FinalStaticData类 * * @author pan_junbiao * */ public class FinalStaticData { private static Random rand = new Random(); // 实例化一个Random类对象 // 随机产生0~10之间的随机数赋予定义为final的a1 private final int a1 = rand.nextInt(10); // 随机产生0~10之间的随机数赋予定义为static final的a2 private static final int a2 = rand.nextInt(10); public static void main(String[] args) { FinalStaticData fdata = new FinalStaticData(); // 实例化一个对象 // 调用定义为final的a1 out.println("重新实例化对象调用a1的值:" + fdata.a1); //6 // 调用定义为static final的a2 out.println("重新实例化对象调用a2的值:" + fdata.a2); //8 // 实例化另外一个对象 FinalStaticData fdata2 = new FinalStaticData(); out.println("重新实例化对象调用a1的值:" + fdata2.a1); //1 out.println("重新实例化对象调用a2的值:" + fdata2.a2); //8 } }
说明被定义为
final static
的变量对象的值是完全不可改变的。内存中为a2开辟了一个恒定不变的区域,当再次实例化一个
FinalStaticData
对象时,仍然指向a2这块内存区域,所以a2的值保存不变。a2是在装载时被初始化,而不是每次创建新对象时被初始化;而a1会重新实例化对象时被更改。
- final的类
- final的方法
-
可变变量
val
:使用
var
声明的变量是可变的,可以被重新赋值。var
适用于需要在程序中多次修改的数据。var userAge: Int = 25 userAge = 26 // 这是允许的
-
二者对比:
-
惰性赋值:只是再使用的时候,才会真正的加载到内存中去。减少内存压力。只能在常量(val)中用,不能再变量(var)中用(适合于大段的常量内容)。
lazy val 名称:类型 = 值
lazy val a = "sdfafweafw" //字符串定义双引号 //插入一下字符串的介绍 val aa = "1111" val bb = "2222" val zz = s"${aa}12345${bb}" //使用s表达式 ${} 类似python的f'{}'
-
val修饰的对象的值是不能改变的。
-
val声明的数组也是不可变的(区别于final)
val arr = Array(1, 2, 3) // arr(0) = 4 // 这将导致编译错误,因为arr是不可变的 val arr = arr.updated(0, 4) // 这是有效的,创建了一个新的数组,并重新赋值给arr变量 重新声明定义赋值不报错 //尝试直接修改数组arr的元素会导致编译错误,因为arr是不可变的。 var arr = Array(1, 2, 3) arr(0) = 4 // 这是有效的,因为arr是可变的 // 如果你想要替换整个数组 arr = Array(5, 6, 7) // 这也是有效的
-
Scala在定变量时,可以不写类型名,Scala编译器可以自动推断。