Skip to content

Scala Variables

Variables are named memory locations used to store values. In Scala, variables are declared using either val or var.

  • val (Value): Defines an immutable variable, similar to a final variable in Java. Once assigned, its reference or value cannot be changed. This is preferred in functional programming for predictability and safety.
val message: String = "Hello, Scala!" // Immutable
// message = "Hi" // This would cause a reassignment compile error
  • var (Variable): Defines a mutable variable. Its value or reference can be reassigned after initialization. Use var when you explicitly need mutable state, but prefer val whenever possible.
var counter: Int = 0 // Mutable
println(s"Counter: $counter") // Output: Counter: 0
counter = counter + 1
println(s"Counter: $counter") // Output: Counter: 1

Best Practice: Always default to using val unless you have a specific reason to need mutability.

The general syntax is:

val variableName: DataType = initialValue
var variableName: DataType = initialValue
  • val or var: Keyword indicating immutability or mutability.
  • variableName: The chosen name for the variable.
  • : DataType: Optional type annotation. Specifies the expected type.
  • = initialValue: The initial value assigned to the variable.

Scala’s compiler features powerful type inference. If you provide an initial value, you can often omit the explicit type annotation, and the compiler will infer it.

val inferredInt = 10 // Compiler infers Int
val inferredString = "Scala" // Compiler infers String
var inferredDouble = 3.14 // Compiler infers Double
// Type annotation is required if no initial value is given (only possible for vars or abstract vals)
// var address: String // Allowed for vars, initialized to null/zero equivalent later
// val name: String // Compile error: vals must be initialized
// Type annotation is also useful for clarity or required when the inferred type is too general
val list: List[Int] = List(1, 2, 3) // Explicit type clarifies it's List[Int]
val anyVal: Any = 42 // Need annotation if assigning to a supertype

Multiple Assignments (Tuple Deconstruction):

Section titled “Multiple Assignments (Tuple Deconstruction):”

Scala allows assigning elements of a tuple (or other structures via pattern matching) to multiple variables simultaneously.

val coordinates = (10, 25) // A Tuple2[Int, Int]
// Deconstruct the tuple into two vals
val (x, y) = coordinates
@main def TupleAssignDemo(): Unit = {
println(s"x = $x, y = $y") // Output: x = 10, y = 25
}
// This also works with case classes
case class User(name: String, age: Int)
val user = User("Alice", 30)
val User(userName, userAge) = user // Extract fields
// Now userName = "Alice", userAge = 30

The scope defines where a variable can be accessed. Scala has several scopes:

Variables defined directly within a class or object body (not inside a method). They are accessible from all methods within that class/object, subject to access modifiers (private, protected). Fields can be val or var.

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

Variables defined in the parameter list of a method. They are accessible only within that method. Method parameters are always immutable (val) within the method’s scope – you cannot reassign them.

def process(input: String, count: Int): Unit = {
// input = "new" // Compile error: reassignment to val input
println(s"Processing '$input' $count times.")
val local = input.length * count // Can use parameters
}

Variables declared inside a method body or any other block (like inside a for loop or if expression). They are only accessible within that block. Local variables can be val or var.

def exampleMethod(): Unit = {
val localVal = "I'm local and immutable"
var localMutable = 0
if (localMutable == 0) {
val blockLocal = true // Only visible inside this 'if' block
println(s"Block local: $blockLocal")
localMutable += 1
}
// println(blockLocal) // Compile error: blockLocal not visible here
println(s"Method local: $localVal, $localMutable")
}