Values, variables and types

Scala · Essentials · 10 min

Immutability by default and inferred static types shape all Scala code.

val x = 10 defines an immutable value; var y = 10 a mutable variable you can reassign. Idiomatic Scala uses val almost everywhere: values that never change are easier to reason about and safe to share between threads.

Types are inferred, so val x = 10 is an Int, but you can annotate: val ratio: Double = 0.5. Annotate public method results and anything where the inferred type isn't obvious.

The basic types are Int, Long, Double, Float, Boolean, Char, String, Byte, Short, plus BigInt and BigDecimal for arbitrary precision. They're all objects with methods (1.to(5), "abc".reverse), but compile to JVM primitives where possible. Unit (written ()) is the type of expressions with no useful value, like println.

The type hierarchy has Any at the top, with AnyVal (number-like types) and AnyRef (objects, i.e. java.lang.Object) below it, and Nothing at the bottom: the type of throw and of expressions that never return.

String interpolation: s"Hi $name, ${a + b}" inserts values, f"$pi%.2f" formats printf-style with type checking, and raw"..." skips escapes. Triple quotes """...""" make multi-line strings; .stripMargin removes leading | margins.

== compares values (it calls equals), so string comparison just works; eq checks reference identity.

Example

val name = "Ada"
var visits = 1
visits += 1
// name = "Bob"            // error: Reassignment to val name

val pi: Double = math.Pi
val big = BigInt(2).pow(100)
println(s"$name visited $visits times")   // Ada visited 2 times
println(f"pi is $pi%.3f")                 // pi is 3.142
println(s"2^100 = ${big.toString.length} digits")  // 2^100 = 31 digits

val a = "scala"
val b = "sca" + "la".trim
println(a == b)                           // true (value equality)
println(7 / 2)                            // 3 (Int division)
println(7 / 2.0)                          // 3.5
println("""|multi
           |line""".stripMargin)          // multi / line

Remember

  • Prefer val; use var only for local, contained mutation
  • Types are inferred; annotate public APIs
  • s"..." interpolates, f"..." formats with type checks
  • == is value equality, eq is reference identity

Watch out for

  • Integer division: 7 / 2 is 3; make one operand a Double for 3.5.

Check yourself

  1. What happens when you reassign a val?
  2. In Scala, what does "ab" == "a" + "b" evaluate to?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.scala-lang.org/scala3/book/taste-vars-data-types.html