变量与常量 #
一、val 与 var #
1.1 val - 不可变变量 #
val 声明的变量是不可变的,一旦赋值就不能改变:
scala
val name = "Scala"
name = "Java"
类似于 Java 的 final 变量。
1.2 var - 可变变量 #
var 声明的变量是可变的:
scala
var counter = 0
counter = 1
counter = 2
println(counter)
1.3 选择原则 #
优先使用 val,原因:
- 代码更安全,减少意外修改
- 并发编程更安全
- 代码更易理解和推理
- 函数式编程风格
scala
val pi = 3.14159
val greeting = "Hello, World!"
val numbers = List(1, 2, 3)
二、类型推断 #
2.1 自动类型推断 #
Scala 会自动推断变量类型:
scala
val name = "Scala"
val age = 25
val pi = 3.14159
val flag = true
println(s"name: ${name.getClass}") // class java.lang.String
println(s"age: ${age.getClass}") // int
println(s"pi: ${pi.getClass}") // double
println(s"flag: ${flag.getClass}") // boolean
2.2 显式类型注解 #
有时需要显式指定类型:
scala
val name: String = "Scala"
val age: Int = 25
val pi: Double = 3.14159
val flag: Boolean = true
2.3 需要显式类型的场景 #
指定特定类型:
scala
val number: Long = 100
val decimal: Float = 3.14f
val chars: Seq[Char] = "Hello".toSeq
避免类型推断歧义:
scala
val empty: List[String] = List()
val nothing: Option[Int] = None
公共 API:
scala
def greet(name: String): String = s"Hello, $name!"
三、延迟初始化 #
3.1 lazy val #
lazy val 延迟初始化,直到第一次访问时才计算:
scala
lazy val expensiveValue = {
println("Computing...")
Thread.sleep(1000)
42
}
println("Before access")
println(expensiveValue)
println(expensiveValue)
输出:
text
Before access
Computing...
42
42
3.2 lazy val 的用途 #
- 延迟昂贵的初始化
- 处理循环依赖
- 按需加载资源
scala
lazy val database = connectToDatabase()
lazy val config = loadConfig()
def processData() =
val db = database
val cfg = config
四、变量的作用域 #
4.1 局部变量 #
在方法或代码块内定义:
scala
def calculate(): Int =
val x = 10
val y = 20
x + y
4.2 成员变量 #
在类或对象中定义:
scala
class Counter:
var count = 0
def increment(): Unit =
count += 1
def current: Int = count
4.3 遮蔽(Shadowing) #
内部作用域可以遮蔽外部变量:
scala
val x = 10
def demo() =
val x = 20
println(s"Inner x: $x")
println(s"Outer x: $x")
demo()
输出:
text
Outer x: 10
Inner x: 20
五、不可变性与可变性 #
5.1 val 引用不可变 #
val 保证引用不可变,但引用的对象可能是可变的:
scala
val buffer = scala.collection.mutable.ListBuffer(1, 2, 3)
buffer += 4
println(buffer)
5.2 不可变集合 #
使用不可变集合保证完全不可变:
scala
val list = List(1, 2, 3)
val newList = list :+ 4
println(list)
println(newList)
5.3 不可变性的好处 #
scala
val config = Map(
"host" -> "localhost",
"port" -> "8080"
)
def getConfig = config
六、类型转换 #
6.1 数值类型转换 #
scala
val intVal = 100
val longVal: Long = intVal
val doubleVal: Double = intVal
6.2 强制类型转换 #
scala
val doubleVal = 3.14
val intVal = doubleVal.toInt
val longVal = 100L
val intVal2 = longVal.toInt
6.3 字符串转换 #
scala
val numStr = "123"
val num = numStr.toInt
val doubleStr = "3.14"
val doubleVal = doubleStr.toDouble
val boolStr = "true"
val boolVal = boolStr.toBoolean
七、占位符初始化 #
7.1 使用 _ 初始化 #
var 变量可以使用 _ 初始化为默认值:
scala
var x: Int = _
var y: Double = _
var z: Boolean = _
var s: String = _
println(x)
println(y)
println(z)
println(s)
7.2 各类型默认值 #
| 类型 | 默认值 |
|---|---|
| Int | 0 |
| Long | 0L |
| Float | 0.0f |
| Double | 0.0 |
| Boolean | false |
| Char | ‘\0’ |
| 引用类型 | null |
7.3 注意事项 #
val 不能使用 _ 初始化:
scala
val x: Int = _
八、多变量声明 #
8.1 元组解构 #
scala
val (name, age) = ("Alice", 25)
println(s"$name is $age years old")
8.2 模式匹配解构 #
scala
val person @ (firstName, lastName) = ("John", "Doe")
println(s"Full name: ${person._1} ${person._2}")
8.3 集合解构 #
scala
val List(a, b, c) = List(1, 2, 3)
println(s"a=$a, b=$b, c=$c")
val head :: tail = List(1, 2, 3, 4, 5)
println(s"head=$head, tail=$tail")
九、最佳实践 #
9.1 优先使用 val #
scala
val result = calculate()
val message = if (result > 0) "positive" else "non-positive"
9.2 使用有意义的名称 #
scala
val maxRetryCount = 3
val connectionTimeout = 5000
var currentIndex = 0
var retryCount = 0
9.3 最小化可变状态 #
scala
def factorial(n: Int): Int =
@annotation.tailrec
def loop(acc: Int, n: Int): Int =
if n <= 1 then acc
else loop(acc * n, n - 1)
loop(1, n)
9.4 使用不可变数据结构 #
scala
val items = List(1, 2, 3)
val newItems = items :+ 4
val filtered = items.filter(_ > 1)
十、总结 #
| 特性 | val | var | lazy val |
|---|---|---|---|
| 可变性 | 不可变 | 可变 | 不可变 |
| 初始化时机 | 立即 | 立即 | 延迟 |
| 线程安全 | 是 | 否 | 是 |
| 推荐程度 | 推荐 | 谨慎使用 | 按需使用 |
关键要点:
- 优先使用 val,减少可变状态
- 使用
lazy val延迟昂贵的初始化 - 理解
val引用不可变与对象可变的区别 - 使用有意义的变量名
下一步,让我们学习 基本数据类型!
最后更新:2026-03-27