题目
Scala中val和var的区别及使用场景
信息
- 类型:问答
- 难度:⭐
考点
变量声明,val与var的区别,不可变性原则
快速回答
在Scala中:
- val 声明不可变变量(赋值后不可修改)
- var 声明可变变量(赋值后可重新赋值)
- 优先使用
val保证不可变性 - 两者都支持类型推断,显式类型标注可选
1. 核心区别
Scala 通过 val 和 var 声明变量:
- val (value):
声明后不可重新赋值,类似 Java 的final变量。val name = "Alice" // 后续 name = "Bob" 会导致编译错误 - var (variable):
声明后可修改值。var count = 0
count = 1 // 允许修改
2. 代码示例
// val 示例(推荐用法)
val pi: Double = 3.14 // 显式类型标注
val message = "Hello" // 类型推断为String
// var 示例(谨慎使用)
var counter = 0
counter += 1 // 允许修改
// 错误示例
val immutableList = List(1, 2, 3)
immutableList = List(4,5) // 编译错误!val不能重新赋值
immutableList :+ 4 // 正确!生成新列表,原列表不变3. 最佳实践
- 优先使用 val:
Scala 鼓励不可变性(immutability),避免副作用,提高代码安全性。 - 限制 var 使用场景:
仅在循环计数器、临时状态等必要场景使用,如:var sum = 0
for (i <- 1 to 10) sum += i - 集合注意点:
val修饰集合时,集合引用不可变,但内容可能可变(如ArrayBuffer)。需区分引用不可变与内容不可变。
4. 常见错误
- 误改 val 变量:
val x = 10
x = 20 // 编译错误:Reassignment to val - 混淆可变性:
val arr = Array(1,2,3)
arr(0) = 9 // 允许!修改数组内容(Array本身可变)
arr = Array(4,5) // 错误!val禁止改变引用
5. 原理说明
- 线程安全性:
val天然线程安全,无需同步。 - 类型推断:两者都支持类型推断,但复杂场景建议显式标注类型:
val ids: List[Int] = List(1, 2) - 编译机制:
val在编译期检查赋值约束,var无此限制。
6. 扩展知识
- 函数式编程:Scala 推崇无副作用编程,大量使用
val和不可变集合。 - lazy val:延迟初始化变量(首次访问时计算),如:
lazy val heavyResource = initExpensiveResource() - 模式匹配:
val在解构时常用:val (name, age) = ("Bob", 30)