Skip to content

Scala 变量

变量(Variable)是用来存储值的命名内存位置。在 Scala 中,变量使用 val 或 var 声明。

  • val (Value): 定义一个 不可变(Immutable)变量,类似于 Java 中的 final 变量。一旦赋值,其引用或值就不能更改。在函数式编程中推荐使用 val,以提高可预测性和安全性。
val message: String = "Hello, Scala!" // 不可变
// message = "Hi" // 这会引发重新赋值的编译错误
  • var (Variable): 定义一个 可变(Mutable)变量。其值或引用在初始化后可以重新赋值。当您明确需要可变状态时使用 var,但尽可能优先使用 val。
var counter: Int = 0 // 可变
println(s"Counter: $counter") // 输出: Counter: 0
counter = counter + 1
println(s"Counter: $counter") // 输出: Counter: 1

最佳实践: 除非您有明确的理由需要可变性,否则始终默认使用 val。

通用语法是:

val variableName: DataType = initialValue
var variableName: DataType = initialValue
  • val 或 var:指示不可变性或可变性的关键字。
  • variableName:为变量选择的名称。
  • : DataType:可选的类型注解(type annotation)。指定预期的类型。
  • = initialValue:赋给变量的初始值。

Scala 的编译器具有强大的类型推断(Type Inference)功能。如果您提供了一个初始值,通常可以省略显式的类型注解,编译器会自动推断类型。

val inferredInt = 10 // 编译器推断为 Int
val inferredString = "Scala" // 编译器推断为 String
var inferredDouble = 3.14 // 编译器推断为 Double
// 如果没有给出初始值,则需要类型注解(仅对 var 或抽象 val 可能)
// var address: String // 对 var 允许,稍后初始化为 null/零 的等价物
// val name: String // 编译错误:val 必须被初始化
// 类型注解也有助于清晰性,或者在推断的类型过于通用时需要
val list: List[Int] = List(1, 2, 3) // 显式类型澄清它是 List[Int]
val anyVal: Any = 42 // 如果赋值给 Any 或其超类型,则需要注解

Scala 允许将元组(或其他结构通过模式匹配)的元素同时赋给多个变量。

val coordinates = (10, 25) // 一个 Tuple2[Int, Int]
// 将元组解构成两个 val
val (x, y) = coordinates
@main def TupleAssignDemo(): Unit = {
println(s"x = $x, y = $y") // 输出: x = 10, y = 25
}
// 这也适用于 case class
case class User(name: String, age: Int)
val user = User("Alice", 30)
val User(userName, userAge) = user // 提取字段
// 现在 userName = "Alice", userAge = 30

作用域(Scope)定义了变量可以在哪里被访问。Scala 有几种作用域:

直接定义在类或对象体内的变量(不在方法内部)。它们可以从该类/对象内的所有方法访问,但受访问修饰符(private、protected)的限制。字段可以是 val 或 var。

class MyClass {
val immutableField = 100 // 字段
var mutableField = "initial" // 字段
def printFields(): Unit = {
println(s"Immutable: $immutableField, Mutable: $mutableField")
}
}

定义在方法的参数列表中的变量。它们 仅 在该方法内部可访问。方法参数在该方法的范围内总是 不可变(val)——您不能重新赋值它们。

def process(input: String, count: Int): Unit = {
// input = "new" // 编译错误:重新赋值给 val input
println(s"Processing '$input' $count times.")
val local = input.length * count // 可以使用参数
}

在方法体或任何其他块(例如 for 循环或 if 表达式内部)中声明的变量。它们只能在该块内部访问。局部变量可以是 val 或 var。

def exampleMethod(): Unit = {
val localVal = "I'm local and immutable"
var localMutable = 0
if (localMutable == 0) {
val blockLocal = true // 仅在此 'if' 块内可见
println(s"Block local: $blockLocal")
localMutable += 1
}
// println(blockLocal) // 编译错误:blockLocal 在此处不可见
println(s"Method local: $localVal, $localMutable")
}