Scala Variables
Scala Variables
Section titled “Scala Variables”Variables are named memory locations used to store values. In Scala, variables are declared using either val or var.
val vs var:
Section titled “val vs var:”val(Value): Defines an immutable variable, similar to afinalvariable 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 errorvar(Variable): Defines a mutable variable. Its value or reference can be reassigned after initialization. Usevarwhen you explicitly need mutable state, but prefervalwhenever possible.
var counter: Int = 0 // Mutableprintln(s"Counter: $counter") // Output: Counter: 0counter = counter + 1println(s"Counter: $counter") // Output: Counter: 1Best Practice: Always default to using val unless you have a specific reason to need mutability.
Variable Declaration Syntax:
Section titled “Variable Declaration Syntax:”The general syntax is:
val variableName: DataType = initialValuevar variableName: DataType = initialValuevalorvar: 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.
Type Inference:
Section titled “Type Inference:”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 Intval inferredString = "Scala" // Compiler infers Stringvar 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 generalval list: List[Int] = List(1, 2, 3) // Explicit type clarifies it's List[Int]val anyVal: Any = 42 // Need annotation if assigning to a supertypeMultiple 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 valsval (x, y) = coordinates
@main def TupleAssignDemo(): Unit = { println(s"x = $x, y = $y") // Output: x = 10, y = 25}
// This also works with case classescase class User(name: String, age: Int)val user = User("Alice", 30)val User(userName, userAge) = user // Extract fields// Now userName = "Alice", userAge = 30Variable Scopes:
Section titled “Variable Scopes:”The scope defines where a variable can be accessed. Scala has several scopes:
Fields (Member Variables):
Section titled “Fields (Member Variables):”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") }}Method Parameters:
Section titled “Method Parameters:”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}Local Variables:
Section titled “Local Variables:”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")}